使用 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>

发现使用可比较集合是去这里的方法,但是在添加新的票证后,我仍然必须再次阅读所有票证。

提前感谢,希西

使用 MVVM 模式将项添加到数据绑定列表框的最佳方法

好的,

这是代码。

假设你在 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