Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/python-2.7/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 从DependencyProperty更新辅助属性_C#_Wpf - Fatal编程技术网

C# 从DependencyProperty更新辅助属性

C# 从DependencyProperty更新辅助属性,c#,wpf,C#,Wpf,我有一个基于TextBox控件的WPF控件: public class DecimalTextBox : TextBox 我有一个绑定到的依赖项属性,它管理数值,并负责设置文本属性: public decimal NumericValue { get { return (decimal)GetValue(NumericValueProperty); } set { if (NumericValue != value) {

我有一个基于TextBox控件的WPF控件:

public class DecimalTextBox : TextBox
我有一个绑定到的依赖项属性,它管理数值,并负责设置文本属性:

public decimal NumericValue
{
    get { return (decimal)GetValue(NumericValueProperty); }
    set
    {
        if (NumericValue != value)
        {
            SetValue(NumericValueProperty, value);
            SetValue(TextProperty, NumericValue.ToString());                    

            System.Diagnostics.Debug.WriteLine($"NumericValue Set to: {value}, formatted: {Text}");
        }
    }
}

protected override void OnTextChanged(TextChangedEventArgs e)
{            
    base.OnTextChanged(e);

    if (decimal.TryParse(Text, out decimal num))
    {
        SetValue(NumericValueProperty, num);
    }
}
当在文本框本身中输入值时(它会更新基础值,等等),这种方法非常有效。但是,更改NumericValue的绑定属性时,尽管更新了NumericValue DP,但文本属性不会更新。在我所做的测试中,出现这种情况的原因似乎是在更新绑定值时没有调用上面的
set
方法。所讨论的绑定如下所示:

<myControls:DecimalTextBox NumericValue="{Binding Path=MyValue, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>


有人能告诉我为什么这个属性setter没有启动,或者有更好的方法吗?

WPF绑定实际上并没有使用getter和setter,而是直接与依赖属性
NumericValueProperty
交互。要更新文本,请订阅
NumericValueProperty
PropertyChanged
事件,而不是尝试在setter中执行任何特殊操作

订阅DependencyProperty定义中的更改,类似于以下内容:

// Using a DependencyProperty as the backing store for NumericValue.  This enables animation, styling, binding, etc...
public static readonly DependencyProperty NumericValueProperty =
    DependencyProperty.Register("NumericValue", typeof(decimal), typeof(DecimalTextBox), new FrameworkPropertyMetadata(0.0m, new PropertyChangedCallback(OnNumericValueChanged)));

private static void OnNumericValueChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
    var self = d as DecimalTextBox;
    // if the new numeric value is different from the text value, update the text
}
如和中所述,除了在依赖项属性的CLR包装中调用
GetValue
SetValue
之外,不应调用任何其他内容:

public decimal NumericValue
{
    get { return (decimal)GetValue(NumericValueProperty); }
    set
    {
        if (NumericValue != value)
        {
            SetValue(NumericValueProperty, value);
            SetValue(TextProperty, NumericValue.ToString());                    

            System.Diagnostics.Debug.WriteLine($"NumericValue Set to: {value}, formatted: {Text}");
        }
    }
}

protected override void OnTextChanged(TextChangedEventArgs e)
{            
    base.OnTextChanged(e);

    if (decimal.TryParse(Text, out decimal num))
    {
        SetValue(NumericValueProperty, num);
    }
}
由于属性设置的XAML processor behavior的当前WPF实现完全绕过了包装器,因此不应在自定义依赖项属性的包装器的集合定义中添加任何附加逻辑。如果将此类逻辑放在集合定义中,那么在XAML而不是代码中设置属性时,将不会执行该逻辑


为了获得有关值更改的通知,您必须向依赖项属性元数据注册
PropertyChangedCallback

public static readonly DependencyProperty NumericValueProperty =
    DependencyProperty.Register(
        "NumericValue", typeof(decimal), typeof(DecimalTextBox),
        new PropertyMetadata(NumericValuePropertyChanged));

public decimal NumericValue
{
    get { return (decimal)GetValue(NumericValueProperty); }
    set { SetValue(NumericValueProperty, value); }
}

private static void NumericValuePropertyChanged(
    DependencyObject obj, DependencyPropertyChangedEventArgs e)
{
    var textBox = (DecimalTextBox)obj;
    textBox.Text = e.NewValue.ToString();
}