即使用户未更新,WPF文本框也会丢失原始值

时间:2010-10-06 20:31:07

标签: wpf binding textbox grid mode

我有一个datagrid,它绑定到Person类型的可观察集合 所选项目绑定到对象人员。 我有2个文本框firstname和lastname。 当用户从网格中选择项目时,将填充文本框值。 用户可以编辑值并单击“提交”按钮,值会更新。

源到目标的工作正常 - 即能够从viewModel显示 当我更新时,值会更新。

让我们说用户选择名字为john,姓名为smith的项目 问题是用户编辑johnny的名字而他没有点击提交按钮,而是从datagrid中选择了一个不同的项目,所以当我回到原来选择的项目时。在网格中,所选项目显示为John smith,但在文本框中,值显示为Johnny smith。

2 个答案:

答案 0 :(得分:1)

谢谢大家。使用De-Activating事件解决了该问题。因此,每当用户点击网格中的新项目时,旧项目De_Activating事件将检查数据是否已从原始项目更改,如果是,它将显示警告消息,供用户转到新项目或留下并完成编辑。如果用户希望留下并完成编辑,则使用e.Cancel = true取消该事件;并且活动记录保留旧项目。如果用户继续进行新选择,则旧值将恢复到对象。

我相信可能有更好的解决方案,我绝对愿意学习。非常感谢您的努力。我真的很感激。

答案 1 :(得分:0)

首先,将DataGrid中的SelectedItem绑定到ObservableCollection中的项目。然后将TextBox控件绑定到DataGrid中的相同SelectedItem(在我的例子中为SelectedCustomer)。然后通过实现INotifyPropertyChanged来更新SelectedCustomer,以使ObservableCollection与SelectedCustomer保持同步。 最后,您可以在TextBox控件中包含UpdateSourceTrigger = PropertyChanged,以便在需要时键入TextBox时更新DataGrid。

我已经包含了以下代码(ViewModelBase除外)以帮助您入门。

这是带有DataGrid和两个TextBox控件的XAML:

<Window x:Class="DataGridTextBox.Views.MainView"
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  xmlns:WpfToolkit="clr-namespace:Microsoft.Windows.Controls;assembly=WPFToolkit" 
  Title="Main Window" Height="400" Width="800">
  <DockPanel>
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>
        <WpfToolkit:DataGrid  
            Grid.Column="0"
            SelectedItem="{Binding Path=SelectedCustomer, Mode=TwoWay}"
            ItemsSource="{Binding Path=Customers, Mode=OneWay}" >
        </WpfToolkit:DataGrid>
        <StackPanel Grid.Column="1">
            <TextBlock Text="First Name"/>
            <TextBox Text="{Binding Path=SelectedCustomer.FirstName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
            <TextBlock Text="Last Name"/>
            <TextBox Text="{Binding Path=SelectedCustomer.LastName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
        </StackPanel>
    </Grid>
  </DockPanel>
</Window>

这是一个简单的ViewModel:

public class MainViewModel : ViewModelBase
{

  public MainViewModel()
  {
     _customers = Customer.GetSampleCustomerList();
     _selectedCustomer = _customers[0];
  }

  private ObservableCollection<Customer> _customers = null;
  public ObservableCollection<Customer> Customers
  {
     get
     {
        return _customers;
     }
  }

  private Customer _selectedCustomer;
  public Customer SelectedCustomer
  {
     get
     {
        return _selectedCustomer;
     }
     set
     {
        _selectedCustomer = value;
        OnPropertyChanged("SelectedCustomer");
     }
  }
}

对于示例代码,我只需在此处将View的DataContext设置为ViewModel:

public partial class App : Application
{
  private void OnStartup(object sender, StartupEventArgs e)
  {
     // Create the ViewModel and expose it using the View's DataContext
     Views.MainView view = new Views.MainView();
     view.DataContext = new ViewModels.MainViewModel();
     view.Show();
  }
}

最后一个简单的客户定义:

public class Customer
{
  public String FirstName { get; set; }
  public String MiddleName { get; set; }
  public String LastName { get; set; }
  public String Address { get; set; }
  public Boolean IsNew { get; set; }

  // A null value for IsSubscribed can indicate 
  // "no preference" or "no response".
  public Boolean? IsSubscribed { get; set; }

  public Customer(String firstName, String lastName,
      String address, Boolean isNew, Boolean? isSubscribed)
  {
     this.FirstName = firstName;
     this.MiddleName = lastName;
     this.LastName = lastName;
     this.Address = address;
     this.IsNew = isNew;
     this.IsSubscribed = isSubscribed;
  }

  public static ObservableCollection<Customer> GetSampleCustomerList()
  {
     return new ObservableCollection<Customer>(new Customer[4] {
            new Customer("Jeff", "Zero", 
                "12 North Third Street, Apartment 45", 
                false, true), 
            new Customer("Joel", "One", 
                "34 West Fifth Street, Apartment 67", 
                false, false),
            new Customer("Jon", "Two", 
                "56 East Seventh Street, Apartment 89", 
                true, null),
            new Customer("Zamboni", "Three", 
                "78 South Ninth Street, Apartment 10", 
                true, true)
        });
  }
}