我正在尝试构建一个WPF应用程序与MVVM模式遵循Caliburn微约定。我有一个PersonModel类,其中声明了三个属性。然后在ShellViewModel类中,我创建了一个BindableCollection,其中我加载了3人模型的信息。在XAML中,我使用ItemControl来创建三个文本框的模板,以便所有3个人的数据显示在3个不同的行中。
我还有另外两个按钮,用于从BindableCollection中添加和删除PersonModel,作为回报,XAML也被更新。到目前为止,它运行良好。现在我创建了另一个按钮名为应用在ShellViewModel;按下该键后,它应该在所有可用的BindableCollection中处理一个操作。
问题是,我正试图实现一个按钮保护应用按钮(CanApply),只有当它发现所有文本框都为所有BindableCollection填充时才会激活。现在我注意到,如果我改变/更新XAML中的任何文本框,它会通知PersonModel类中的绑定属性,但我需要在ShellViewModel中定义BindableCollection和CanApply()。
PersonModel
public class PersonModel
{
public string FirstName { get; set; }
public string LastName { get; set; }
public int Age { get; set; }
}
ShellViewModel
public class ShellViewModel
{
public BindableCollection<PersonModel> People { get; set; }
public ShellViewModel()
{
DataAccess da = new DataAccess();
People = new BindableCollection<PersonModel>() {
new PersonModel { FirstName = "John", LastName= "Smith", Age = 30},
new PersonModel { FirstName = "Bob", LastName= "Marry", Age = 21},
new PersonModel { FirstName = "", LastName= "Milito", Age = 16}
};
}
public void AddPerson()
{
DataAccess dataAccess = new DataAccess();
//int maxId = 0;
if (People.Count > 0)
{
People.Add(new PersonModel());
}
}
public void RemovePerson()
{
DataAccess dataAccess = new DataAccess();
if (People.Count == 0)
{
return;
}
PersonModel randomPerson = dataAccess.GetRandomItem(People.ToArray());
People.Remove(randomPerson);
}
public bool CanApply() {
bool output = false;
foreach (var item in People) {
output = false;
if (!string.IsNullOrEmpty(item.FirstName)) {
output = true;
}
}
return output;
}
public void Apply() {
}
}
XAML
<Window x:Class="WPFDemoUI.Views.ShellView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WPFDemoUI.Views"
mc:Ignorable="d" FontSize="20" WindowStartupLocation="CenterScreen"
Title="ShellView" Height="450" Width="800">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="auto" />
<RowDefinition Height="auto" />
<RowDefinition Height="auto" />
<RowDefinition Height="auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<StackPanel Orientation="Horizontal" Grid.Row="0">
<Button x:Name="AddPerson">Add New Person</Button>
<Button x:Name="RemovePerson" Margin="10 0 0 0">Remove Random Person</Button>
<Button x:Name="Apply" Margin="10 0 0 0">Apply</Button>
</StackPanel>
<ItemsControl x:Name="People" Grid.Row="1">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Border BorderBrush="Black" BorderThickness="1" Margin="10" Padding="10">
<StackPanel Orientation="Horizontal">
<TextBox Text="{Binding FirstName, Mode=TwoWay}" MinWidth="50" />
<TextBox Text="{Binding LastName, Mode=TwoWay}" MinWidth="50" />
<TextBox Text="{Binding Age, Mode=TwoWay}" MinWidth="50"/>
</StackPanel>
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
</Window>
处理此问题的通常方法是使用您选择的MVVM框架中的ICommand
实现。然而,这份原稿。Micro似乎没有命令。相反,它们有称为动作的东西,但功能非常相似。这里是实现一个按钮点击方法(SayHello
)的一个例子,随着它的条件(CanSayHello
)直接采取了Caliburn。微的文档:
using System.Windows;
public class ShellViewModel : IShell
{
public bool CanSayHello(string name)
{
return !string.IsNullOrWhiteSpace(name);
}
public void SayHello(string name)
{
MessageBox.Show(string.Format("Hello {0}!", name));
}
}
<UserControl x:Class="Caliburn.Micro.HelloParameters.ShellView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
xmlns:cal="http://www.caliburnproject.org">
<StackPanel>
<TextBox x:Name="Name" />
<Button Content="Click Me">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Click">
<cal:ActionMessage MethodName="SayHello">
<cal:Parameter Value="{Binding ElementName=Name, Path=Text}" />
</cal:ActionMessage>
</i:EventTrigger>
</i:Interaction.Triggers>
</Button>
</StackPanel>
</UserControl>
根据文档的工作方式是:
当找到
SayHello
消息的处理程序时,它将检查该类是否也具有名为CanSayHello
的属性或方法