首先解决上一篇博客未解决的问题。上次博客中还有一种命令(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的用法。