WPF样式设置器不起作用 [英] WPF style setter not working

查看:130
本文介绍了WPF样式设置器不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个包含组合框的自定义用户控件.我添加了一个ComboBoxWidth依赖项属性,以允许开发人员根据需要设置宽度.使用样式设置器,我想在所有用户控件上将所有这些组合框的宽度设置为相同的值,以实现尺寸一致性.但是,它不起作用.如果我分别在每个控件上设置大小,它将起作用.在样式设置器中指定大小后,将忽略该大小.如果我将属性字符串从"ComboBoxWidth"更改为"Width",则所有控件的整个宽度都会更改.因此,看起来样式格式是正确的.我想念什么吗?这是我第一次尝试将样式应用于自己的自定义依赖项属性.

I have a custom user control that contains a combo box. I've added a ComboBoxWidth dependency property to allow developer to set width if they want. Using a style setter, I'd like to set the widths for all these combo boxes to the same value on another user control for size consistency. But, it is not working. It works if I set the size separately on each control. When the size is specified in the style setter, it is ignored. If I change the Property string from "ComboBoxWidth" to "Width", the entire width of all the controls are changed. So, it looks like the style formatting is correct. Am I missing something? This is the first time I've tried to apply a style to my own custom dependency property.

注意:AngleUserControl基于通用用户控件(不包括任何在代码中创建的xaml--控件). ComboBoxWidth探测器在通用基类中.我不确定这是否与此有关.

Note: AngleUserControl is based off a generic user control (that doesn't include any xaml--control created in code). The ComboBoxWidth proberty is in the generic base class. I'm not sure if that has anything to do with it or not.

样式代码(在包含几个AngleUserControl控件的用户控件中):

Style code (in user control containing several AngleUserControl controls):

<UserControl.Resources>
    <Style TargetType="wpfControls:AngleUserControl">
        <Setter Property="ComboBoxWidth" Value="400"/>
    </Style>
</UserControl.Resources>

UnitControlBase:

UnitControlBase:

/// <summary>
/// Control that displays value in different units depending on selected unit type.
/// </summary>
/// <typeparam name="TSelectionTypeEnum">The enumeration type for all the available units.</typeparam>
/// <typeparam name="TConverterType">The MultiValueConverter that converts the value between the different types of units.</typeparam>
/// <typeparam name="TValueType">The underlying type of the stored value.</typeparam>
public class UnitControlBase<TSelectionTypeEnum, TConverterType, TValueType> : UserControl
    where TSelectionTypeEnum : struct, IConvertible
    where TConverterType : IMultiValueConverter, new()
{
    #region Private Fields

    // Metadata for the dependency properties.
    private static FrameworkPropertyMetadata valuePropertyMetadata = new FrameworkPropertyMetadata(default(TValueType));
    private static FrameworkPropertyMetadata valueTypePropertyMetadata = new FrameworkPropertyMetadata(default(TSelectionTypeEnum));
    private static FrameworkPropertyMetadata displayValueTypePropertyMetadata = new FrameworkPropertyMetadata(default(TSelectionTypeEnum));
    private static FrameworkPropertyMetadata comboBoxWidthPropertyMetadata = new FrameworkPropertyMetadata(0.0);
    private static FrameworkPropertyMetadata valueFormatPropertyMetadata = new FrameworkPropertyMetadata(string.Empty);

    #endregion

    #region Constructor

    /// <summary>
    /// Constructor
    /// </summary>
    public UnitControlBase()
    {
        ValueFormat = "#,##0.00";
        ComboBoxWidth = 75.0;

        // Create main grid and add to control.
        Grid mainGrid = new Grid();
        mainGrid.Name = "LayoutRoot";
        this.AddChild(mainGrid);

        // Create grid columns.
        ColumnDefinition col1 = new ColumnDefinition();
        col1.Width = GridLength.Auto;
        ColumnDefinition col2 = new ColumnDefinition();
        mainGrid.ColumnDefinitions.Add(col1);
        mainGrid.ColumnDefinitions.Add(col2);

        // Create the text box that will display the value.
        Label displayValueLabel = new Label();
        displayValueLabel.Name = "DisplayValueLabel";
        Grid.SetColumn(displayValueLabel, 0);
        mainGrid.Children.Add(displayValueLabel);

        // Bind to the multi-value converter that will convert between the types.
        MultiBinding mb = new MultiBinding();
        mb.Converter = new TConverterType();
        mb.Bindings.Add(new Binding("Value") { Source = this });
        mb.Bindings.Add(new Binding("ValueType") { Source = this });
        mb.Bindings.Add(new Binding("DisplayValueType") { Source = this });
        mb.Bindings.Add(new Binding("ValueFormat") { Source = this });
        displayValueLabel.SetBinding(Label.ContentProperty, mb);
        displayValueLabel.HorizontalContentAlignment = System.Windows.HorizontalAlignment.Right;            

        // Create the combo box that will display selected unit.
        ComboBox displayValueComboBox = new ComboBox();
        displayValueComboBox.Name = "DisplayValueComboBox";
        displayValueComboBox.SetBinding(ComboBox.WidthProperty, new Binding("ComboBoxWidth") { Source = this });
        Grid.SetColumn(displayValueComboBox, 1);
        mainGrid.Children.Add(displayValueComboBox);

        // Bind available units and selected units.
        displayValueComboBox.ItemsSource = Enum.GetValues(typeof(TSelectionTypeEnum));
        displayValueComboBox.SetBinding(ComboBox.SelectedItemProperty, new Binding("DisplayValueType") { Source = this });
    }

    #endregion

    #region Dependency Properties

    /// <summary>
    /// Value Dependency Property
    /// </summary>
    public static readonly DependencyProperty ValueProperty =
        DependencyProperty.Register("Value", typeof(TValueType), typeof(UnitControlBase<TSelectionTypeEnum, TConverterType, TValueType>), valuePropertyMetadata);

    /// <summary>
    /// Value Type Dependency Property
    /// </summary>
    public static readonly DependencyProperty ValueTypeProperty =
        DependencyProperty.Register("ValueType", typeof(TSelectionTypeEnum), typeof(UnitControlBase<TSelectionTypeEnum, TConverterType, TValueType>), valueTypePropertyMetadata);

    /// <summary>
    /// Display Value Type Dependency Property
    /// </summary>
    public static readonly DependencyProperty DisplayValueTypeProperty =
        DependencyProperty.Register("DisplayValueType", typeof(TSelectionTypeEnum), typeof(UnitControlBase<TSelectionTypeEnum, TConverterType, TValueType>), displayValueTypePropertyMetadata);

    /// <summary>
    /// Combo Box Width Dependency Property
    /// </summary>
    public static readonly DependencyProperty ComboBoxWidthProperty =
        DependencyProperty.Register("ComboBoxWidth", typeof(double), typeof(UnitControlBase<TSelectionTypeEnum, TConverterType, TValueType>), comboBoxWidthPropertyMetadata);

    /// <summary>
    /// Value Format Dependency Property
    /// </summary>
    public static readonly DependencyProperty ValueFormatProperty =
        DependencyProperty.Register("ValueFormat", typeof(string), typeof(UnitControlBase<TSelectionTypeEnum, TConverterType, TValueType>), valueFormatPropertyMetadata);

    #endregion

    #region Public Properties

    /// <summary>
    /// The underlying stored value.
    /// </summary>
    public TValueType Value
    {
        get
        {
            return (TValueType)GetValue(ValueProperty);
        }
        set
        {
            SetValue(ValueProperty, value);
        }
    }

    /// <summary>
    /// The unit type for the underlying stored value.
    /// </summary>
    public TSelectionTypeEnum ValueType
    {
        get
        {
            return (TSelectionTypeEnum)GetValue(ValueTypeProperty);
        }
        set
        {
            SetValue(ValueProperty, value);
        }
    }

    /// <summary>
    /// The unit type for the displayed value.
    /// </summary>
    public TSelectionTypeEnum DisplayValueType
    {
        get
        {
            return (TSelectionTypeEnum)GetValue(DisplayValueTypeProperty);
        }
        set
        {
            SetValue(DisplayValueTypeProperty, value);
        }
    }

    /// <summary>
    /// Width of combo box displaying available units.
    /// </summary>
    public double ComboBoxWidth
    {
        get
        {
            return (double)GetValue(ComboBoxWidthProperty);
        }
        set
        {
            SetValue(ComboBoxWidthProperty, value);
        }
    }

    /// <summary>
    /// The format of the displayed value.
    /// </summary>
    public string ValueFormat
    {
        get
        {
            return (string)GetValue(ValueFormatProperty);
        }
        set
        {
            SetValue(ValueFormatProperty, value);
        }
    }

    #endregion
}

AngleUserControl.cs

AngleUserControl.cs

/// <summary>
/// Control allowing user to display a value in degrees, radians, or semicircles.
/// </summary>
public class AngleUserControl : UnitControlBase<AngleSelectionType, AngleMultiValueConverter, double>
{
    #region Constructor

    /// <summary>
    /// Constructor.
    /// </summary>
    public AngleUserControl()
    {
        this.ComboBoxWidth = 175.0;
    }

    #endregion
}

推荐答案

依赖项属性的所谓局部值",例如

A so-called "local value" of a dependency property, like

this.ComboBoxWidth = 175.0;

具有比样式设置器中的值更高的值优先级,例如

has higher value precedence than a value from a Style Setter, like

<Setter Property="ComboBoxWidth" Value="400"/>

因此样式设置器无效.

您应该通过覆盖依赖项属性元数据来分配新的默认值:

You should assign a new default value by overriding dependency property metadata:

public class AngleUserControl : ...
{
    static AngleUserControl()
    {
        ComboBoxWidthProperty.OverrideMetadata(
            typeof(AngleUserControl),
            new PropertyMetadata(175d));
    }
}

请参见依赖属性值优先级供参考.

这篇关于WPF样式设置器不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆