2016-05-19 2 views
2

У меня есть DataGrid, связанный с коллекцией People. Также у меня есть TextBox, который должен принять значение Name из выбранной строки. Затем пользователь может отредактировать значение или оставить его как есть. Ключевым моментом является то, что текст, отображаемый в TextBox независимо от того, происходит ли он из коллекции или пользовательского ввода, должен быть передан в свойство NewName.WPF Multibinding: привязка OneWayToSource от TextBox, обновленная с помощью другого связывания, не работает?

Я установил два привязок для NewNameTextBox: OneWay'ed к CollectionView за DataGrid и OneWayToSource'ed к собственности:

<Window.Resources> 
    <CollectionViewSource x:Key="PeopleCollection" 
     Source="{Binding Path=People, Mode=OneWay}" /> 
    <local:ConverterNewNamePrefill x:Key="ConverterNewNamePrefill" /> 
</Window.Resources> 
<Grid> 
    <StackPanel> 
     <DataGrid ItemsSource="{Binding Source={StaticResource PeopleCollection}}" 
        AutoGenerateColumns="True" 
        IsReadOnly="True" 
        Margin="10"> 
     </DataGrid> 
     <StackPanel Orientation="Horizontal" Margin="10"> 
      <TextBox> 
       <TextBox.Text> 
        <MultiBinding Converter="{StaticResource ConverterNewNamePrefill}" > 
         <Binding Source="{StaticResource PeopleCollection}" Path="Name" Mode="OneWay" /> 
         <Binding Path="NewName" Mode="OneWayToSource" /> 
        </MultiBinding> 
       </TextBox.Text> 
      </TextBox> 
     </StackPanel> 
    </StackPanel> 
</Grid> 

Я полагаю, что собственность должна быть обновлена, когда пользователь изменяет выбор в DataGrid, но этого не происходит. TextBox обновляется и отображает выбранное значение Name, но свойство, связанное через OneWayToSource, остается неизменным.

Если пользователь вводит текст в TextBox, свойство обновляется, как ожидалось.

Итак, вопрос в том, как я могу обновить свойство из обоих источников через многострочный TextBox без кода за точкой зрения?

Вот код за окном: метод

public class Person 
{ 
     public string Name { get; set; } 
     public string Surname { get; set; } 
} 

public partial class MainWindow : Window 
{ 

    public MainWindow() 
    { 
     InitializeComponent(); 
    } 

    private ObservableCollection<Person> _people = new ObservableCollection<Person> { 
     new Person() {Name = "Mitchell", Surname = "Sofia" }, 
     new Person() {Name="Bush", Surname="Ethan" }, 
     new Person() {Name="Ferrero", Surname="Emma" }, 
     new Person() {Name="Thompson", Surname="Aiden" } 
    }; 
    public ObservableCollection<Person> People => _people; 

    public string NewName { get; set; } = "Jackson"; 
} 

public class ConverterNewNamePrefill : IMultiValueConverter 
{ 

    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) 
    { 
     return values[0]; 
    } 

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) 
    { 
     return new[] { value, value }; 
    } 
} 

преобразователя ConvertBack() вызывается только тогда, когда пользователь, но не тогда, когда TextBox.Text обновляется из коллекции.

Спасибо!

ответ

0

Вот как работают привязки. Источник или источники не обновляются, если цель не изменяется с помощью других средств, кроме самой привязки. То есть предполагается, что если цель была просто обновлена ​​из источника (ов), то источник (ы) уже (уже) обновлен и не нуждается в обновлении.

Без лишних подробностей трудно точно знать, что вы хотите. Но похоже, что вы можете либо хотеть для NewName, чтобы на самом деле быть target второй привязки, где источник является тем же самым свойством Name, которое используется в качестве источника для свойства TextBox.Text, или вы хотите подписаться на событие TextBox.TextChanged и ваш обработчик явно записывает значение в свойство NewName, когда это событие поднято.

В первом случае вам нужно будет сделать NewName зависимым свойством MainWindow. Это осложнение, с которым вы можете или не хотите иметь дело. Если нет, то я рекомендую последний подход.

Смежные вопросы