【问题标题】:Multi binding, a better solution?多重绑定,更好的解决方案?
【发布时间】:2013-07-21 16:25:06
【问题描述】:

我有一个通过 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();
  }
}

【问题讨论】:

    标签: c# wpf binding multibinding


    【解决方案1】:

    如果您不遗余力地遵循 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>
    

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-11-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-07-20
      • 2011-11-21
      相关资源
      最近更新 更多