简体   繁体   English

C# 在 WPF 中绑定 CustomControl 属性

[英]C# Binding CustomControl property in WPF

I'm using this as a guideline to try to create a extend a control.以此为指导来尝试创建扩展控件。 This extended control has to be used in a user control.此扩展控件必须在用户控件中使用。

The custom control extends the Button and has a DependencyProperty Length :自定义控件扩展了Button并具有DependencyProperty Length

public class SquareButton : Button
{
    static SquareButton()
    {
        DefaultStyleKeyProperty.OverrideMetadata(typeof(SquareButton),
            new FrameworkPropertyMetadata(typeof(SquareButton)));
    }

    public static readonly DependencyProperty LengthProperty = DependencyProperty.Register(
        "Length",
        typeof(double),
        typeof(SquareButton),
        new FrameworkPropertyMetadata(20));

    public double Length
    {
        get => (double) this.GetValue(LengthProperty);
        set => this.SetValue(LengthProperty, value);
    }
}

The Themes/Generic.xaml merges the resource dictionary xaml file for this control: Themes/Generic.xaml Generic.xaml 为这个控件合并了资源字典 xaml 文件:

<ResourceDictionary.MergedDictionaries>
    <ResourceDictionary
        Source="/OwnControls;component/Input/CustomControl/SquareButton.xaml" />
</ResourceDictionary.MergedDictionaries>

The file SquareButton.xaml is defined in a ResourceDictionary and tries to set a width property:文件SquareButton.xamlResourceDictionary中定义并尝试设置宽度属性:

<Style
    TargetType="local:SquareButton"
    BasedOn="{StaticResource {x:Type Button}}">
    <Setter
        Property="Width"
        Value="100">
    </Setter>
</Style>

Now I need to bind the Width property to the dependency property `Length of the SquareButton control but I don't know how and I can't find it.现在我需要将Width属性绑定到 SquareButton 控件的依赖属性“Length”,但我不知道怎么做,也找不到。 Things I've tried:我尝试过的事情:

<Setter
    Property="Width"
    Value="{Binding Path=Length, RelativeSource={RelativeSource TemplatedParent}, 
    Mode=OneWay}">
</Setter>

but this has no effect on the width of the button.但这对按钮的宽度没有影响。 I also tried我也试过

<Setter
    Property="Width"
    Value="{TemplateBinding Length}">
</Setter>

but this give a compile error:但这会产生编译错误:

'Length' member is not valid because it does not have a qualifying type name. 'Length' 成员无效,因为它没有限定类型名称。

The SquareButton control is being used in a UserControl like this: SquareButton控件在UserControl中使用,如下所示:

<customControl:SquareButton
    Length="100"
    Content="1" />

How can I bind the Length in SquareButton.xaml to the Length property of the SquareButton extended control?如何将SquareButton.xaml中的Length绑定到 SquareButton 扩展控件的Length属性?

Since you own the code for SquareButton , you have a lot of power.由于您拥有SquareButton的代码,因此您拥有很大的权力。 There are some different techniques you'll learn as you build more custom controls.随着您构建更多自定义控件,您将学习一些不同的技术。

One is using property changed callbacks on your custom dependency properties.一种是在您的自定义依赖属性上使用属性更改回调。 In the example below, I use one for Length so that I can set Width and Height .在下面的示例中,我使用一个作为Length以便我可以设置WidthHeight

Another is adding property changed callbacks on existing dependency properties that you don't own.另一个是在您不拥有的现有依赖项属性上添加属性更改回调。 This can be done using a DependencyPropertyDescriptor .这可以使用DependencyPropertyDescriptor来完成。 In the example below I setup callbacks for Width and Height, so I can keep everything in sync.在下面的示例中,我为宽度和高度设置了回调,因此我可以使所有内容保持同步。

This little control can make use of both of these techniques.这个小控件可以利用这两种技术。 Essentially, you need Length to control Width and Height, but also need to handle changes to Width and Height to keep everything in sync and square!本质上,您需要 Length 来控制 Width 和 Height,但还需要处理 Width 和 Height 的更改以保持一切同步和正方形!

Here is an example using those techniques:以下是使用这些技术的示例:

using System;
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;

namespace WpfApp4
{
    public class SquareButton : Button
    {
        private static bool isSizeChanging;

        static SquareButton()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(SquareButton), new FrameworkPropertyMetadata(typeof(SquareButton)));
        }

        public SquareButton()
        {
            var widthPropertyDescriptor = DependencyPropertyDescriptor.FromProperty(WidthProperty, typeof(SquareButton));
            widthPropertyDescriptor.AddValueChanged(this, OnWidthChanged);

            var heightPropertyDescriptor = DependencyPropertyDescriptor.FromProperty(HeightProperty, typeof(SquareButton));
            heightPropertyDescriptor.AddValueChanged(this, OnHeightChanged);

        }

        private void OnWidthChanged(object sender, EventArgs e)
        {
            if (isSizeChanging) return;
            isSizeChanging = true;
            Length = Width;
            Height = Width;
            isSizeChanging = false;
        }

        private void OnHeightChanged(object sender, EventArgs e)
        {
            if (isSizeChanging) return;
            isSizeChanging = true;
            Length = Height;
            Width = Height;
            isSizeChanging = false;
        }

        #region Length (DependencyProperty)
        public static readonly DependencyProperty LengthProperty =
            DependencyProperty.Register(
                "Length",
                typeof(double),
                typeof(SquareButton),
                new PropertyMetadata(20d, OnLengthChanged));

        public double Length
        {
            get => (double)GetValue(LengthProperty);
            set => SetValue(LengthProperty, value);
        }

        private static void OnLengthChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (!(d is SquareButton button) || isSizeChanging) return;
            isSizeChanging = true;
            button.Width = button.Length;
            button.Height = button.Length;
            isSizeChanging = false;
        }
        #endregion
    }
}

I hope this helps!我希望这有帮助!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM