UserControl:如何转换依赖属性并绑定到结果

Posted

技术标签:

【中文标题】UserControl:如何转换依赖属性并绑定到结果【英文标题】:UserControl: how to convert dependency properties and bind to the result 【发布时间】:2019-05-17 00:09:02 【问题描述】:

我有一个 XAML 用户控件,一个标签、一个文本框和一个组合框的组合。 在文本框中,我键入一个双精度值,它必须根据我在组合框中的选择确定的系数进行调整。总是 ! (实际上是一个单位转换操作:米到公里,英尺到厘米等) 这样,我将始终在程序“内部”拥有一致的 SI 单位 这样做的合乎逻辑的地方是在 UserControl 的代码隐藏中。 因此我定义了一个 Dep Prop InternalValue,它将包含文本框的调整值。 我需要能够绑定到那个 DP。 我试图做类似下面代码的事情,但这不会成功:我在 TextChanged 中得到指示的编译错误。 我怎样才能做我想做的事?

        public string  TBText
    
        get  return (string)GetValue(TBTextProperty); 
        set  SetValue(TBTextProperty, value); 
    

    public static readonly DependencyProperty TBTextProperty =
        DependencyProperty.Register("TBText", typeof(string), typeof(UCInputField), new PropertyMetadata( new PropertyChangedCallback(TextChanged)));

    private static void TextChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    
        InternalValue = Convert.ToDouble(e.NewValue) * factor; // error: an object reference is required.

    

    public double InternalValue
    
        get  return (double)GetValue(InternalValueProperty); 
        set  SetValue(InternalValueProperty, value); 
    

    public static DependencyProperty InternalValueProperty =
        DependencyProperty.Register("InternalValue", typeof(double), typeof(UCInputField));


    public DimPostfix CBSelectedItem
    
        get  return (DimPostfix)GetValue(CBSelectedItemProperty); 
        set  SetValue(CBSelectedItemProperty, value); 
    

    public static readonly DependencyProperty CBSelectedItemProperty =
        DependencyProperty.Register("CBSelectedItem", typeof(DimPostfix), typeof(UCInputField),new PropertyMetadata(new PropertyChangedCallback(UnitChanged)));

    static double factor;
    private static void UnitChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    
        factor = (e.NewValue as DimPostfix).Factor;
    

这里是用户控件:

    <UserControl
    x:Class="MyProgram.Views.UCInputField"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    d:DesignHeight="45"
    d:DesignWidth="250"
    mc:Ignorable="d">

    <StackPanel
        x:Name="LayoutRoot"
        Orientation="Horizontal">
        <Label      
            Content="Binding LBContent"
            Style="StaticResource LabelStyle1" />
        <TextBox
            x:Name="TB"
            HorizontalAlignment="Stretch"
            Text="Binding TBText, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged"/>
        <ComboBox
            x:Name="CBBox"
            Width="70"
            DisplayMemberPath="Name"
            ItemsSource="Binding CBUnit"
            SelectedItem="Binding CBSelectedItem"/>
    </StackPanel>
    </UserControl>

并且控件会这样使用:

<ip:UCInputField
  CBSelectedItem="Binding ....."
  CBUnit="Binding ...."
  LBContent="Length"
  InternalValue="Binding ..."
  TBText="Binding Path=Ucl, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged"/>

【问题讨论】:

【参考方案1】:

如您所见,TextChanged 是一个静态方法。因此,如果您想更改那里的属性,它需要引用您的用户控件的实例。 方法参数之一是 DependencyObject 类型,它是拥有已更改的依赖属性的对象,可以转换到您的用户控件中。

private static void TextChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    
        var myControl = (UCInputField)d; //This is the reference that is needed
        myControl.InternalValue = Convert.ToDouble(e.NewValue) * factor; //You can user factor since it is static
    

【讨论】:

以上是关于UserControl:如何转换依赖属性并绑定到结果的主要内容,如果未能解决你的问题,请参考以下文章

绑定到 UserControl XAML 中的依赖属性

为啥在数据模板中使用 xaml UserControl 时无法绑定到依赖属性? [复制]

使用该控件时的 MVVM UserControl 和绑定

具有属性绑定的自定义 UserControl 模板

数据绑定到 WPF 中的 UserControl

如何设置控件属性(在DataTemplate和UserControl中)的绑定以使用ItemSource的给定属性?