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