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

时间:2013-07-22 19:38:31

标签: c# wpf binding multibinding

我有一个文本框,通过XAML绑定到列表框, 文本框也绑定到视图模型,使用多重绑定 要获得这一点,请参阅下文。

想法是必须在之前修改所选项目 在视图模型中使用。

我对这段代码不满意,为这么简单的任务复杂化。 每个绑定完全独立。可以使用哪种简单方法 选择一个元素修改它并使用修改后的字符串 在视图模型中进一步处理?

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

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

1 个答案:

答案 0 :(得分:4)

如果您遵循MVVM,您最终会在VM中添加其他属性。因此,绑定来源为Data,当前所选项目为SelectedItem,文本框中的值为ModifiedItem。然后在您的XAML中,每个控件都只绑定到VM,而不是以任何方式绑定到彼此。 (我经常发现当控件彼此绑定时,这意味着VM有点不发达。当然,有时简单性胜过架构纯粹主义。)

<Window ...>
    ...
    <StackPanel>
        <TextBox Name="textBox" Text="{Binding ModifiedItem}" />
        <ListBox Name="listBox" ItemsSource="{Binding Data}" SelectedItem="{Binding SelectedItem}" />
    </StackPanel>
</Window>

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