使用 MVVM 模式将项添加到数据绑定列表框的最佳方法
本文关键字:列表 最佳 方法 数据绑定 模式 MVVM 添加 使用 | 更新日期: 2024-10-24 01:50:31
我现在在WPF项目中遇到了一个问题。目前,我有一个视图模型,它有一个管理器(与存储库通信(。
internal class TicketViewModel
{
private TicketManager mgr;
public IEnumerable<Ticket> List { get; set; }
public TicketViewModel()
{
mgr = new TicketManager();
List = mgr.GetTickets();
}
}
我已经设法将此列表绑定到主窗口中的列表框。下一步是我需要在列表中添加一个额外的票证,并通过管理器传递它。问题是我需要来自主窗口中某些控件的两个参数。从 MVVM 的角度来看,我需要在例如按钮上使用绑定命令来与视图模型通信,因为我的视图模型不能/可能无法从窗口访问控件。使用参数化命令是这里的方式吗?
下一个问题是我猜列表框不会更新。这是代码:
<ListBox x:Name="listboxTix" BorderThickness="0" ItemsSource="{Binding List}">
<ListBox.ItemTemplate>
<DataTemplate>
<Border BorderBrush="Bisque" Background="Beige" BorderThickness="2">
<StackPanel Width="250">
<TextBlock Text="{Binding TicketNumber}" />
<TextBlock Text="{Binding Text}" />
<TextBlock Text="{Binding State}" />
</StackPanel>
</Border>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
我发现使用可比较集合是去这里的方法,但是在添加新的票证后,我仍然必须再次阅读所有票证。
提前感谢,希西
好的,
这是代码。
假设你在 MainWindow 上有三个文本框(因为你有三个文本块(,所以你的 MainWindow.xaml 看起来像
<Window.DataContext>
<local:MyViewModel/>--set's your viewModel
</Window.DataContext>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="250*"/>
<RowDefinition Height="90"/>
<RowDefinition Height="30"/>
</Grid.RowDefinitions>
<ListBox Grid.Row="0" x:Name="listboxTix" BorderThickness="0" ItemsSource="{Binding List}">
<ListBox.ItemTemplate>
<DataTemplate>
<Border BorderBrush="Bisque" Background="Beige" BorderThickness="2">
<StackPanel Width="250">
<TextBlock Text="{Binding TicketNumber}" />
<TextBlock Text="{Binding Text}" />
<TextBlock Text="{Binding State}" />
</StackPanel>
</Border>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<TextBox x:Name="TicketNumber" Grid.Row="1" TextWrapping="Wrap" Text="{Binding Path=Text}" VerticalAlignment="Top" Width="120"/>
<TextBox x:Name="Text" Grid.Row="1" TextWrapping="Wrap" Text="{Binding Path=State}" />
<TextBox x:Name="State" Grid.Row="1" TextWrapping="Wrap" Text="{Binding Path=TicketNumber}" />
<Button Content="Button" Command="{Binding Path=MainCommand}" Grid.Row="2"/>
</Grid>
我假设您有一个称为类票的类,其中包含这三个成员
Class Ticket
{
public int TicketNumber { get; set; }
public string Text { get; set; }
public string State { get; set; }
}
现在在课堂上 票务管理器 我们用一些虚拟数据填充它
class TicketManager
{
ObservableCollection<Ticket> tl = new ObservableCollection<Ticket>();
internal ObservableCollection<Ticket> GetTickets()
{
tl.Add(new Ticket() { State = "State1", Text = "Text1", TicketNumber = 1 });
tl.Add(new Ticket() { State = "State2", Text = "Text2", TicketNumber = 2 });
tl.Add(new Ticket() { State = "State3", Text = "Text3", TicketNumber = 3 });
return tl;
}
}
在您的主窗口视图模型中,我们将其称为MyViewModel.cs我们添加
class MyViewModel:INotifyPropertyChanged
{
private TicketManager mgr;
public ObservableCollection<Ticket> List { get; set; }
private string text;
private string state;
private int ticketNumber;
private readonly DelegateCommand<object> MyButtonCommand;
public Class1()
{
mgr = new TicketManager();
List = mgr.GetTickets();
MyButtonCommand = new DelegateCommand<object>((s) => { AddListToGrid(text, state, ticketNumber); }, (s) => { return !string.IsNullOrEmpty(text) && !string.IsNullOrEmpty(state); });
}
private void AddListToGrid(string text, string state, int ticketNumber)
{
List.Add(new Ticket() {Text=text,State=state,TicketNumber=ticketNumber });
}
public DelegateCommand<object> MainCommand
{
get
{
return MyButtonCommand;
}
}
public string Text
{
get
{
return text;
}
set
{
text = value;
OnPropertyChanged("Text");
MyButtonCommand.RaiseCanExecuteChanged();
}
}
public string State
{
get
{
return state;
}
set
{
state = value;
OnPropertyChanged("State");
MyButtonCommand.RaiseCanExecuteChanged();
}
}
public int TicketNumber
{
get
{
return ticketNumber;
}
set
{
ticketNumber = value;
OnPropertyChanged("TicketNumber");
MyButtonCommand.RaiseCanExecuteChanged();
}
}
private void OnPropertyChanged(string p)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(p));
}
public event PropertyChangedEventHandler PropertyChanged;
}
您可以根据需要修改代码
这个视图模型实现了从 MVVM 的角度来看非常重要的一些东西
1( 不可信属性变更
2( WPF 委托命令
PS:代码经过测试,按预期运行
不要纠
结于MVVM
它只是将数据与视图分离,并且模型在两者之间共享,大多数业务逻辑(在共享组件上(应该在 VM 上执行; 它不是一个宗教,只是一个三层数据系统。恕我直言
如果您的按钮需要执行操作,请让它调用(很可能在代码隐藏中(VM
上处理业务逻辑的方法,使用新项更新列表并通知经理。
我会将有问题的列表绑定到一个可以在插入/删除项目时通知的ObservableCollection
。