C# 多绑定,更好的解决方案?

C# 多绑定,更好的解决方案?,c#,wpf,binding,multibinding,C#,Wpf,Binding,Multibinding,我有一个通过XAML绑定到列表框的文本框, 文本框也绑定到视图模型,使用多重绑定 要获得此信息,请参见下文 其思想是,必须先修改所选项目,然后再修改它 在视图模型中使用 我对这段代码不满意,对于这样一个简单的任务来说太复杂了。 每种装订都能完美地单独工作。可以使用哪种简单的方法 要选择一个元素,请修改它并将修改后的字符串用于 视图模型中的进一步处理 --------------XAML-------------- 如果您严格遵循MVVM,那么您的VM中会有一个额外的属性。因此,对于绑定源,Dat

我有一个通过XAML绑定到列表框的文本框, 文本框也绑定到视图模型,使用多重绑定 要获得此信息,请参见下文

其思想是,必须先修改所选项目,然后再修改它 在视图模型中使用

我对这段代码不满意,对于这样一个简单的任务来说太复杂了。 每种装订都能完美地单独工作。可以使用哪种简单的方法 要选择一个元素,请修改它并将修改后的字符串用于 视图模型中的进一步处理

--------------XAML--------------


如果您严格遵循MVVM,那么您的VM中会有一个额外的属性。因此,对于绑定源,
Data
,对于当前选中的项,
SelectedItem
,对于文本框中的值,
ModifiedItem
。然后在XAML中,每个控件将只绑定到VM,而不是以任何方式彼此绑定。(我通常发现,当控件彼此绑定时,这意味着VM有点不发达。当然,有时简单性胜过了架构纯粹主义。)


...

请注意,当
SelectedItem
属性更改时,将由VM设置
ModifiedItem
。然后,由于
Text
属性上的双向绑定,
TextBox
将写回同一个属性。

如果您严格遵循MVVM,您的VM中会有一个额外的属性。因此,对于绑定源,
Data
,对于当前选中的项,
SelectedItem
,对于文本框中的值,
ModifiedItem
。然后在XAML中,每个控件将只绑定到VM,而不是以任何方式彼此绑定。(我通常发现,当控件彼此绑定时,这意味着VM有点不发达。当然,有时简单性胜过了架构纯粹主义。)


...
请注意,当
SelectedItem
属性更改时,将由VM设置
ModifiedItem
。由于
Text
属性上存在双向绑定,因此
TextBox
将写回该属性

<Window x:Class="WpfApplication1.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:WpfApplication1"
    Title="MainWindow" Height="350" Width="525">
<Window.Resources>
    <local:TheMultiValueConverter x:Key="theConverter"/>
</Window.Resources>
<StackPanel>
    <TextBox Name="textBox">
        <TextBox.Text>
            <MultiBinding Converter="{StaticResource theConverter}" Mode="OneWay">
                <Binding/>
                <Binding ElementName="textBox" Path="Text"/>
                <Binding ElementName="listBox" Path="SelectedItem" Mode="OneWay"/>
            </MultiBinding>
        </TextBox.Text>
    </TextBox>
    <ListBox Name="listBox" ItemsSource="{Binding Data}" />
</StackPanel>
</Window>
public class ViewModel : INotifyPropertyChanged
{
  string modified;
  public string Modified
  {
    get { return modified; }
    set
    {
      if (modified != value)
      {
        modified = value;
        NotifyPropertyChanged("Modified");
      }
    }
  }

  List<string> data = new List<string> { "Test1", "Test2" };
  public List<string> Data
  {
    get { return data; }
  }

  public event PropertyChangedEventHandler PropertyChanged;
  private void NotifyPropertyChanged(string propertyName)
  {
    PropertyChangedEventHandler handler = PropertyChanged;
    if (handler != null)
    {
      handler(this, new PropertyChangedEventArgs(propertyName));
    }
  }
}
public class TheMultiValueConverter : IMultiValueConverter
{
  public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
  {
    var viewModel = values[0] as ViewModel;

    if (viewModel != null)
    {
      viewModel.Modified = (string)values[1];

      if (string.IsNullOrWhiteSpace(values[1].ToString()))
        return values[2];
      else
        return values[1];
    }

    return null;
  }

  public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
  {
    throw new NotImplementedException();
  }
}
<Window ...>
    ...
    <StackPanel>
        <TextBox Name="textBox" Text="{Binding ModifiedItem}" />
        <ListBox Name="listBox" ItemsSource="{Binding Data}" SelectedItem="{Binding SelectedItem}" />
    </StackPanel>
</Window>