2013-07-22 42 views
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

如果你遵循MVVM的信件,你会最终在虚拟机中有一个额外的属性。因此,对于绑定源,您将有Data,对于当前选定项目,SelectedItem,对于文本框中的值,将有ModifiedItem。然后在你的XAML中,你的每个控件只会绑定到虚拟机,而不是以任何方式相互绑定。 (我经常发现,当控件绑定到彼此,这意味着虚拟机是有点落后。当然,有时简单胜于建筑的纯粹。)

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

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

+0

完美,感谢Gunter :) – Bertrand

相关问题