0

我有一个文本框,它通过 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();
  }
}
4

1 回答 1

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属性。

于 2013-07-22T21:09:45.343 回答