清除TextBox并从ObservableCollection更新DataGrid

时间:2013-11-06 00:27:05

标签: c# wpf xaml mvvm binding

我正在使用MVVM模式编写WPF应用程序。我使用TabControl创建了UI。在一个选项卡中,我有一个我公司的客户列表,在另一个选项卡中,我有一个用于添加新客户的表单。我想要两件事:

  1. 添加新客户 - >按下带有客户的选项卡时列表中的新位置
  2. 添加客户端后清除表单文本框
  3. 它们都不起作用。

    我的DataGrid部分:

    <StackPanel DataContext="{StaticResource ClientsVM}">
        <Image HorizontalAlignment="Left" VerticalAlignment="Top" Source="pack://application:,,,/Insurance company;component/Resources/logo.png" Height="100" Margin="5,15,0,0"/>
        <DataGrid  Name="ClientsGrid" ItemsSource="{Binding Clients, Mode=TwoWay}" IsReadOnly="True" Margin="130,0" AutoGenerateColumns="False" ColumnWidth="101">
            <DataGrid.Columns>
                <DataGridTextColumn Header="Client ID" Binding="{Binding ClientId}"/>
                <DataGridTextColumn Header="Name" Binding="{Binding Name}"/>
                <DataGridTextColumn Header="Surname" Binding="{Binding Surname}"/>
                <DataGridTextColumn Header="PESEL" Binding="{Binding PESEL}" />
            </DataGrid.Columns>
            <DataGrid.InputBindings>
                <MouseBinding Gesture="LeftDoubleClick" Command="{Binding ClientsGridLeftDoubleClickCommand}" CommandParameter="{Binding ElementName=ClientsGrid, Path=SelectedItem}" />
            </DataGrid.InputBindings>
        </DataGrid>
    </StackPanel>
    

    我的ViewModel的一部分:

    private ObservableCollection<ClientSet> _clients;
    
    public ObservableCollection<ClientSet> Clients
    {
        get { return _clients; }
        set
        {
            if (_clients != value)
            {
                _clients = value;
                RaisePropertyChanged(() => "Clients");
            }
        }
    }
    

    不幸的是,做了类似的事情:

    _clients = new ObservableCollection<ClientSet>(updatedListOfClientsHere);
    

    不起作用。为什么不呢?

    另一件事是清除表格。它看起来像这样:

    <Label Grid.Row="1" Grid.Column="0" HorizontalAlignment="Left" VerticalAlignment="Bottom" Width="100" FontSize="15">Surname</Label>
    <TextBox Grid.Row="1" Grid.Column="1" HorizontalAlignment="Left" VerticalAlignment="Bottom" Width="141" Name="Surname" Text="{Binding Client.Surname, Mode=TwoWay, ValidatesOnDataErrors=True}"/>
    <Label Grid.Row="2" Grid.Column="0" HorizontalAlignment="Left" VerticalAlignment="Bottom" Width="100" FontSize="15">Name</Label>
    <TextBox Grid.Row="2" Grid.Column="1" HorizontalAlignment="Left" VerticalAlignment="Bottom" Width="141" Name="Name" Text="{Binding Client.Name, Mode=TwoWay, ValidatesOnDataErrors=True}" />
    

    用户键入的值正确反映在ViewModel类中。但是如果我在ViewModel中清除它们 - UI中没有任何反应。我的ViewModel的一部分:

    private ClientSet _client;
    
    public ClientSet Client
    {
        get { return _client; }
        set
        {
            if (value != _client)
            {
                _client = value;
                RaisePropertyChanged(() => "Client");
            };
        }
    }
    
    // Some code
    
    // Clearing the form:
    _client = new ClientSet(); // This shouldn't work?
    Client.Name = string.empty; // This should work!!!
    

    我现在真的没有想法。

2 个答案:

答案 0 :(得分:0)

我不完全确定你在问什么,但让我们看看:

首先,使用您的可观察集合,您无需再次设置它。如果您创建一个新客户端,您只需要:

Clients.Add(new_client_object);

这就是全部。否则,如果创建客户端需要一段时间,您的程序将变慢(我已经看到这种情况发生了,请相信我......)

如果我理解正确,您希望在添加后清除添加新客户端中的项目。你需要做的就是确保内容控件(希望你的添加客户端视图是一个用户控件或类似的东西)接收一个类型为client的对象,然后添加它之后,只需将其设置为null,或者放一个新的(空的)对象,或手动将它们设置为空字符串(确保备份以防您想要取消,或者不要覆盖新的客户端字段)。

您可以添加一些屏幕截图来阐明您想要/需要的内容。

答案 1 :(得分:0)

我注意到你的问题有一些问题。首先,只有在不希望UI更新时,才能在视图模型中调用任何属性的私有成员。如果您希望更新UI,那么您必须使用公共属性,因为这是通知INotifyPropertyChanged接口(通过您的RaisePropertyChanged方法)。因此,要清除客户端列表,只需调用:

Clients = new ObservableCollection<ClientSet>(updatedListOfClientsHere);

接下来,我不确定,因为你没有展示你的ClientSet课程,但我猜你没有在其中实现INotifyPropertyChanged界面。但是,您仍然希望更新该类的属性更改...除非您在该类中实现它,否则将不会在视图模型中包装每个属性并从那里调用RaisePropertyChanged方法。然后,调用Client.Name = string.empty;将清除该字段。

相关问题