如何更新ListBox DataSource On Button Click

时间:2015-02-18 10:36:59

标签: c# wpf mvvm

我有一个ListBox;

  <ListBox Grid.Row="1" Grid.ColumnSpan="2"
                 x:Name="customerListBox"
                 ItemsSource="{Binding Customers}"
                 DisplayMemberPath="Customername"
                 SelectionMode="Single" Width="200"/>

客户为public ObservableCollection<Customer> Customers { get; private set; }

现在我将ListBox Selected Item绑定到文本框:

<TextBox Text="{Binding ElementName=customerListBox,
Path=SelectedValue.Customername,Mode=OneWay}"/>

我已将其设为单向,因为我只想在单击“保存”按钮时提交更改,而不是在TextBlock上更改值时提交更改。

<Button Content="Save" Grid.Column="0" Grid.Row="3" Width="80" Height="30"
                           Command="{Binding SaveCommand}" 

2 个答案:

答案 0 :(得分:2)

你对此采取了错误的方式,imho。

不要将TextBox直接绑定到所选项目。而是创建一个新命令SelectionChangedCommand和新属性CurrentlyActiveText,将其绑定到TextBox

逻辑很简单:

SelectionChangedCommand = new RelayCommand(selectedItem=> {
   // todo: ask user if he wants to commit the previous changes?!
   CurrentlyActiveText = (string)selectedItem;
 })

 SaveCommand = new RelayCommand(() => {
   yourObservable[SelectedIndex] = CurrentlyActiveText;
 });

答案 1 :(得分:0)

也许更好的方法是使用触发器在ListBox SelectionChanged事件上触发命令。将逻辑置于属性设置器中对我来说总是感觉有点错误

<ListBox...>
    <i:Interaction.Triggers>
        <i:EventTrigger EventName="SelectionChanged">
           <i:InvokeCommandAction Command="{Binding CustomerListBoxSelectionChanged}" CommandParameter="{Binding ElementName=customerListBox,Path=SelectedItem}"/>
        </i:EventTrigger>
    </i:Interaction.Triggers>
</ListBox>

在您的视图模型中:

public Customer CurrentCustomer { get; set; }

public RelayCommand<Customer> CustomerListBoxSelectionChanged { get; set; }

private void OnCustomerListBoxSelectionChanged(Customer customer)
{
    CurrentCustomer = customer;
    NewCustomerName = customer.CustomerName;
}

private string _newCustomerName;

public string NewCustomerName
{
    get { return _newCustomerName; }
    set
    {
        if (_newCustomerName == value)
            return;

         _newCustomerName = value;
         RaisePropertyChanged("NewCustomerName");
    }
}

XAML中的TextBox变为:

<TextBox Text="{Binding NewCustomerName}"/>

最后,你的SaveCommand调用一个简单的方法......

private void OnSave()
{
    CurrentCustomer.CustomerName = NewCustomerName;
}

请注意,您还需要确保Customer对象中的CustomerName正在引发PropertyChanged事件,以反映ListBox中的更新

请注意,以这种方式执行此操作还可以节省您进一步查找ObservableCollection以执行更新。它可以为您节省一些时间 - 任何性能提升总是好的:)