You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

UWP自定义UserControl仅字符串属性生效 枚举、布尔等类型属性赋值失效

问题根源

你遇到的问题本质是两个原因导致的:

  1. UWP自定义控件需要在XAML中赋值、支持变更响应的属性,必须定义为依赖属性,普通CLR属性的XAML赋值时机晚于控件构造函数执行,且没有内置变更通知能力
  2. 你根据ValueUnit计算UnitSymbol的逻辑只执行了一次(大概率写在构造函数中),此时XAML给ValueUnit赋的值还未生效,拿到的永远是枚举的默认值Size

解决步骤

1. 把普通CLR属性改为依赖属性

所有需要在XAML中赋值的控件属性,都需要定义为依赖属性,示例代码如下:

// ValueUnit依赖属性
public Unit ValueUnit
{
    get { return (Unit)GetValue(ValueUnitProperty); }
    set { SetValue(ValueUnitProperty, value); }
}

public static readonly DependencyProperty ValueUnitProperty =
    DependencyProperty.Register("ValueUnit", typeof(Unit), typeof(NumericBox), new PropertyMetadata(Unit.Size, OnValueUnitChanged));

// HasCalc依赖属性
public bool HasCalc
{
    get { return (bool)GetValue(HasCalcProperty); }
    set { SetValue(HasCalcProperty, value); }
}

public static readonly DependencyProperty HasCalcProperty =
    DependencyProperty.Register("HasCalc", typeof(bool), typeof(NumericBox), new PropertyMetadata(false));

// Header依赖属性(推荐改为依赖属性保证绑定兼容性,之前生效是因为字符串类型CLR属性的赋值时机刚好命中读取时机)
public string Header
{
    get { return (string)GetValue(HeaderProperty); }
    set { SetValue(HeaderProperty, value); }
}

public static readonly DependencyProperty HeaderProperty =
    DependencyProperty.Register("Header", typeof(string), typeof(NumericBox), new PropertyMetadata(string.Empty));

2. 在属性变更回调中执行单位符号计算逻辑

上面定义ValueUnit依赖属性时注册了OnValueUnitChanged回调,把你之前的switch逻辑放到这个回调中,只要ValueUnit值发生变化就会自动触发重新计算单位符号:

private static void OnValueUnitChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
    if (d is NumericBox numericBox)
    {
        var unit = (Unit)e.NewValue;
        switch (unit)
        {
            case Unit.Currency:
                numericBox.UnitSymbol = System.Globalization.NumberFormatInfo.CurrentInfo.CurrencySymbol;
                break;
            case Unit.Percentage:
                numericBox.UnitSymbol = "%";
                break;
            case Unit.Size:
                if (System.Globalization.RegionInfo.CurrentRegion.IsMetric) 
                    numericBox.UnitSymbol = "m";
                break;
            case Unit.Weight:
                if (System.Globalization.RegionInfo.CurrentRegion.IsMetric) 
                    numericBox.UnitSymbol = "Kg";
                break;
        }
    }
}

3. 给UnitSymbol添加变更通知(可选,推荐)

如果你使用x:Bind的默认OneTime绑定模式,可能出现值更新后界面不刷新的问题,建议给UnitSymbol实现INotifyPropertyChanged接口,同时把绑定模式改为OneWay:

// 首先让你的UserControl实现INotifyPropertyChanged接口
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged([CallerMemberName] string propertyName = "")
{
    PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}

private string _unitSymbol;
public string UnitSymbol
{
    get => _unitSymbol;
    set
    {
        _unitSymbol = value;
        NotifyPropertyChanged();
    }
}

对应XAML绑定修改为:

<TextBlock Text="{x:Bind UnitSymbol, Mode=OneWay}" VerticalAlignment="Center" Margin="5"/>

修改完成后所有XAML中设置的属性就会正常生效,ValueUnit变更后也会自动更新展示的单位符号。


内容的提问来源于stack exchange,提问作者David Simões

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.08 02:18:03