WPF Textbox теряет исходные значения, даже если пользователь не обновляет - PullRequest
1 голос
/ 07 октября 2010

У меня есть сетка данных, которая привязывается к наблюдаемой коллекции типа Person. Выбранный элемент привязывается к Object Person.У меня есть 2 текстовых поля имя и фамилия.Когда пользователь выбирает элемент из сетки, значения текстового поля заполняются.Пользователь может редактировать значения и нажимать кнопку «Отправить», значения обновляются.

Source to Target работает правильно - то есть может отображаться из viewModel. Когда я обновляю значения, обновляется.

Допустим, пользователь выбранэлемент с именем john, фамилия smith Проблема в том, что пользователь редактирует имя johnny, и он не нажимает кнопку отправки, а вместо этого выбирает другой элемент из сетки данных, поэтому, когда я возвращаюсь к исходному выбранному элементу.В сетке выбранный элемент отображается как Джон Смит, но в текстовом поле значение отображается как Джонни Смит.

Ответы [ 2 ]

1 голос
/ 08 октября 2010

Спасибо всем. Проблема решена с помощью события Деактивация. поэтому всякий раз, когда пользователь щелкает новый элемент в сетке, событие De_Activating старого элемента будет проверять, изменились ли данные по сравнению с исходным, если да, будет отображаться предупреждающее сообщение для пользователя, чтобы либо перейти на новый элемент, либо вернуться назад и завершить редактирование. Если пользователь желает остаться и завершить редактирование, событие отменяется с помощью e.Cancel = true; и активная запись остается со старым элементом. если пользователь продолжает новый выбор, старые значения восстанавливаются для объекта.

Я уверен, что могло бы быть намного лучшее решение, и я определенно желаю учиться. Большое спасибо за ваши усилия. Я действительно ценю это.

0 голосов
/ 07 октября 2010

Для начала свяжите с SelectedItem в DataGrid с элементом из ObservableCollection.Затем привяжите элементы управления TextBox к тому же SelectedItem из DataGrid (в моем случае SelectedCustomer).Затем обновите SelectedCustomer путем реализации INotifyPropertyChanged, чтобы сохранить синхронизацию ObservableCollection с SelectedCustomer.Наконец, вы можете включить UpdateSourceTrigger = PropertyChanged в элементы управления TextBox, чтобы обновить DataGrid при вводе текста в TextBox, если это необходимо.

Я включил приведенный ниже код (кроме ViewModelBase), чтобы начать работу.* Вот XAML с DataGrid и двумя элементами управления TextBox:

<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");
     }
  }
}

Для примера кода я просто устанавливаю 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)
        });
  }
}
...