如何像使用代理一样使用绑定


<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;
        }
    }

但这是强烈建议

相关内容

  • 没有找到相关文章

最新更新