首先解決上一篇部落格未解決的問題。上次部落格中還有一種命令(BoundCommad)沒講到。
命令源還是不變的。變得是:我們對命令源封裝成屬性:
命令源ShowMessageCommand:
代碼public class ShowMessageCommand { [Preview("CanExecute")] public void Execute(string message) { MessageBox.Show(message); } public bool CanExecute(string message) { return !string.IsNullOrEmpty(message); } }
建立一個MainModel類,對ShowMessageCommand封裝成屬性。
public class MainModel { private readonly ShowMessageCommand _myCommand = new ShowMessageCommand(); public ShowMessageCommand MyCommand { get { return _myCommand; } } }
xaml:
<Window.DataContext> <local:MainModel /></Window.DataContext><StackPanel> <TextBox Name="message" Width="200" /> <Button Content="BoundCommand" cal:Message.Attach="BoundCommand MyCommand(message.Text)"/></StackPanel>這裡注意是DataContent。DataContext與Resource的區別是
DataContext一般用於綁定資料,相當於資料來源。
Resource一般用於對資源的引用,比如 StaticResource,DynamicResource等。
運行效果:
CompositeCommands
Caliburn中的命令還有層次關係。
還是用原來的資源。稍作修改。
App.xaml.cs
代碼public App() { var container= new SimpleContainer(); CaliburnFramework.ConfigureCore(container).WithPresentationFramework().Start(); container.RegisterSingleton<ShowMessageCommand>("ShowMessage"); container.RegisterSingleton<ShowTitleMessageCommand>("ShowTitleMessage"); }
這裡用到了注入容器來實現命令。
ShowTitleMessageCommand.cs類
代碼public class ShowTitleMessageCommand { [Preview("CanExecute")] [AsyncAction(Callback="CallBack",BlockInteraction=true)] public MessageInfo Execute(string title,string message) { return new MessageInfo() { Message=message,Title=title}; } public bool CanExecute(string title,string message) { return !string.IsNullOrEmpty(title); } public void CallBack(MessageInfo messageInfo) { MessageBox.Show(messageInfo.Message,messageInfo.Title,MessageBoxButton.OK); } public class MessageInfo { public string Message { get; set; } public string Title { get; set; } } }
ShowMessageCommand.cs類
代碼public class ShowMessageCommand { [Preview("CanExecute")] [AsyncAction(Callback="CallBack",BlockInteraction=true)] public string Execute(string message) { // Thread.Sleep(2000); return "you message is"+message; } public bool CanExecute(string message) { return !string.IsNullOrWhiteSpace(message); } public void CallBack(string message) { MessageBox.Show(message); } }
後台資料都準備好了。
xaml
代碼<Window.Resources> <cal:AllCommand x:Key="Grandfather"/> <cal:AllCommand x:Key="All"/> <cal:AnyCommand x:Key="Any"/> </Window.Resources> <StackPanel> <Button Content="全?局?命ü令?" cal:Message.Attach="ResourceCommand Grandfather"/> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition /> <ColumnDefinition /> </Grid.ColumnDefinitions> <GroupBox Header="All composite"> <StackPanel> <TextBox x:Name="allMessage"/> <TextBox x:Name="allTitle"/> <Button Content="All Composite" cal:Command.Parent="{StaticResource Grandfather}" cal:Message.Attach="ResourceCommand All"/> <Button Content="Container Command MessageAndTitle" cal:Command.Parent="{StaticResource All}" cal:Message.Attach="ContainerCommand ShowTitleMessage(allMessage.Text,allTitle.Text)"/> <Button Content="Container Command Message" cal:Command.Parent="{StaticResource All}" cal:Message.Attach="ContainerCommand ShowMessage(allMessage.Text)"/> </StackPanel> </GroupBox> <GroupBox Header="Any Composite" Grid.Column="1"> <StackPanel> <TextBox x:Name="anyMessage" /> <TextBox x:Name="anyTitle" /> <Button Content="Any Composite" cal:Command.Parent="{StaticResource Grandfather}" cal:Message.Attach="ResourceCommand Any" /> <Button Content=" Container Command Message" cal:Command.Parent="{StaticResource Any}" cal:Message.Attach="ContainerCommand ShowMessage(anyMessage.Text)" /> <Button Content="Container Command MessageAndTitle" cal:Command.Parent="{StaticResource Any}" cal:Message.Attach="ContainerCommand ShowTitleMessage(anyMessage.Text, anyTitle.Text)" /> </StackPanel> </GroupBox> </Grid> </StackPanel>
這裡我們用到AllCommand和AnyCommand。
Caliburn上說 AllCommand需要它的子命令都可用,父命令才能執行,相當於“And”邏輯。
而AnyCommand只要它的子命令有一個正確,就可以執行,相當於“or”邏輯 。
我們也可以定義自己的邏輯,通過ICompositeCommand介面。
運行效果:
重點:cal:Command.Parent的用法。