<Setter Property="IsChecked">
<Setter.Value>
<MultiBinding>
<!-- Get value for property -->
<Binding Path="IsPressed" RelativeSource="{RelativeSource Self}" Mode="OneWay"/>
<!-- Set value to ViewModel's property -->
<Binding Path="Shift" Mode="OneWayToSource"/>
</MultiBinding>
</Setter.Value>
</Setter>
我需要为属性使用2个绑定:一个为属性获取值,一个为ViewModel的属性设置值。我如何实现这个场景?
您可以创建两个附加属性。一个将是绑定的目标,另一个将包含代理的绑定。例子:然后在ProxySource OnChange实现中,你将获得TextBox作为元素,在那里你可以从ProxySource读取值并将其写入ProxyTarget。这不是一个非常干净的方法,但它应该可以工作。如果您不能让它工作,我可以稍后编写一个完整的示例。好了,我已经实现了所有的东西,这是完整的源代码:
public class ViewModel : ViewModelBase
{
string sourceText;
public string SourceText
{
get { return sourceText; }
set
{
if (sourceText == value) return;
sourceText = value;
System.Diagnostics.Debug.WriteLine("SourceText:" + value);
RaisePropertyChanged("SourceText");
}
}
string targetText;
public string TargetText
{
get { return targetText; }
set
{
if (targetText == value) return;
targetText = value;
System.Diagnostics.Debug.WriteLine("TargetText:" + value);
RaisePropertyChanged("TargetText");
}
}
}
public static class AttachedPropertiesHost
{
public static object GetProxySource(DependencyObject obj)
{
return obj.GetValue(ProxySourceProperty);
}
public static void SetProxySource(DependencyObject obj, object value)
{
obj.SetValue(ProxySourceProperty, value);
}
public static readonly DependencyProperty ProxySourceProperty =
DependencyProperty.RegisterAttached(
"ProxySource", typeof(object), typeof(AttachedPropertiesHost),
new UIPropertyMetadata(null, ProxySourcePropertyPropertyChanged)
);
private static void ProxySourcePropertyPropertyChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e)
{
dependencyObject.Dispatcher.BeginInvoke(
new { Dp = dependencyObject, NewValue = e.NewValue },
args => SetProxyTarget(args.Dp, args.NewValue)
);
}
public static object GetProxyTarget(DependencyObject obj)
{
return obj.GetValue(ProxyTargetProperty);
}
public static void SetProxyTarget(DependencyObject obj, object value)
{
obj.SetValue(ProxyTargetProperty, value);
}
public static readonly DependencyProperty ProxyTargetProperty =
DependencyProperty.RegisterAttached("ProxyTarget", typeof(object), typeof(AttachedPropertiesHost));
}
<TextBox Text="{Binding SourceText, UpdateSourceTrigger=PropertyChanged}"
WpfDataGridLayout:AttachedPropertiesHost.ProxySource="{Binding RelativeSource={RelativeSource Self}, Path=Text, UpdateSourceTrigger=PropertyChanged}"
WpfDataGridLayout:AttachedPropertiesHost.ProxyTarget="{Binding TargetText, Mode=OneWayToSource}"
/>
以及编辑文本框时控制台的输出:SourceText: fTargetText: fSourceText:跳频TargetText:跳频SourceText: fhhTargetText: fhh
请不要围绕IsPressed
设计您的解决方案,这实际上是一些人所谓的flash
数据,这意味着它会很快变回默认值(false)。此外,Binding
将有专门的目标,源和模式。在MultiBinding
实现一种方式IsPressed
(从一个源)和其他方式保存回另一个Target
是不支持的。为了实现双向更新,所有绑定必须为TowWay
。
尽管Hack可以使用MultiConverter
本身具有Target
作为值之一。
<MultiBinding Converter="MyMultiBindingConverter">
<!-- Get value for property -->
<Binding Path="IsPressed"
RelativeSource="{RelativeSource Self}" Mode="OneWay"/>
<!-- Set value to ViewModel's property -->
<Binding BindsDirectlyToSource="True"/>
</MultiBinding>
MyMultiBindingConverter.Convert()
{
var myViewModel = values[1] as MyViewModel;
var isPressed = bool.Parse(values[0].ToString());
if (isPressed)
{
myViewModel.Shift = !myViewModel.Shift;
}
}
但这是强烈建议不