WPF 依赖属性

WPF Dependency Property(WPF 依赖属性)

本文介绍了WPF 依赖属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在努力了解 WPF 中的依赖属性,可能是因为我正在寻找的用例非常具体,并且没有很好的文档记录.

I'm struggling to get my head around dependency properties in WPF, maybe because the use case I'm looking for is very specific and not well documented.

我拥有的是一个看起来像这样的自定义控件(请忽略所有糟糕的代码,它是临时的!):

What I have is a custom control that looks like this (please do ignore all the terrible code, it is temporary!):

<UserControl x:Class="HydroAccessory.Controls.FillGraph"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
         xmlns:local="clr-namespace:HydroAccessory.Controls"
         mc:Ignorable="d"
         SizeChanged="FillGraph_SizeChanged"
         d:DesignHeight="200" d:DesignWidth="300">
<Grid>

    <TextBlock x:Name="PercentageTB" Text="Fill Percentage: 0%" />

</Grid>

我在我的主窗口中这样称呼它:

I call it inside my main window like this:

<controls:FillGraph x:Name="HydroModel" />

控件里面的代码如下:

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

namespace HydroAccessory.Controls
{
public partial class FillGraph : UserControl
{
    private float percentage;
    public float Percentage
    {
        get
        {
            return percentage;
        }
        set
        {
            percentage = value;
            PercentageTB.Text = String.Format("Fill Percentage: {0}", percentage.ToString() + "%");
        }
    }

    public FillGraph()
    {
        InitializeComponent();
    }
}
}

我想要做的就是在主窗口的自定义控件调用中说:

All that I want to be able to do is say in my custom control call in the main window:

<controls:FillGraph x:Name="HydroModel" Percentage="{Binding FillPercentage}" />

(FillPercentage 是另一个脚本中的内容,您无需担心).该控件将被扩展,因此它需要保留为自定义控件.我知道我可能需要依赖属性,但是在尝试了许多不同的方法之后,我无法弄清楚如何完成这个看似简单的任务.感谢您的帮助.

(Where FillPercentage is something in another script that you don't need to worry about). The control will be expanded, so it needs to stay as a custom control. I understand I may need dependency properties, but after trying many different ways I cannot figure out how to do this seemingly simple task. Help is appreciated.

推荐答案

您的代码中没有依赖属性.

There isn't a dependency property in your code.

这是一个依赖属性:

public partial class FillGraph : UserControl
{
    public FillGraph()
    {
        InitializeComponent();
    }

    public float Percentage
    {
        get { return (float)GetValue(PercentageProperty); }
        set { SetValue(PercentageProperty, value); }
    }

    //  Using a DependencyProperty as the backing store for Percentage.  This 
    //  enables animation, styling, binding, etc...
    public static readonly DependencyProperty PercentageProperty =
        DependencyProperty.Register("Percentage", typeof(float), 
                typeof(FillGraph), new PropertyMetadata(0.0f));
}

正如 Ayyappan Subramanian 所建议的,Visual Studio 中的 propdp 片段将有助于创建样板.请注意传递给 DependencyProperty.Register() 的参数,并确保传递给 new PropertyMetadata() 的默认值是正确的类型.0.0f 是一个浮点数.如果您为 float 属性传递整数 0,它将在运行时引发异常.

As Ayyappan Subramanian suggests, the propdp snippet in Visual Studio will help create the boilerplate. Just be careful with the parameters you pass to DependencyProperty.Register(), and make sure the default value you pass to new PropertyMetadata() is the correct type. 0.0f is a float. If you pass integer 0 for a float property, it'll throw an exception at runtime.

这里的常规属性 public float Percentage 是可选的.它只是供您的代码使用.XAML 根本不会触及它(如果您怀疑我,请在 getter 和 setter 中放置断点).这是依赖属性特别之处的一部分.

The regular property public float Percentage here is optional. It's just there for your code to use. XAML won't ever touch it at all (put breakpoints in the getter and setter if you doubt me). That's part of what's special about dependency properties.

下面是如何在您的用户控件 XAML 中使用它.请注意绑定的 StringFormat 参数.

And here's how to use it in your usercontrol XAML. Note the StringFormat parameter to the binding.

<Grid>
    <TextBlock 
        Text="{Binding Percentage, RelativeSource={RelativeSource AncestorType=UserControl}, StringFormat='Fill Percentage: {0:#.##}%'}" 
        />
</Grid>

注意:如果您的百分比表示在 0 到 1 而不是 0 到 100 的范围内,请改用 p 百分比格式.我们将使用 p2 表示小数点后的两位数.我们省略了 % 因为格式字符串提供了它.

Note: If your percentage is expressed in the range 0 to 1 rather than 0 to 100, use the p percent format instead. We'll use p2 for two digits after the decimal point. We omit the % because the format string provides that.

    <TextBlock 
        Text="{Binding Percentage, StringFormat='Fill Percentage: {0:p2}', RelativeSource={RelativeSource AncestorType=UserControl}}" 
        />

假设 viewmodel 具有 FillPercentage 属性并正确实现 INotifyPropertyChanged,则您的问题中的这个 XAML 很好:

This XAML from your question is fine just as it is, assuming that the viewmodel has a FillPercentage property and correctly implements INotifyPropertyChanged:

<controls:FillGraph x:Name="HydroModel" Percentage="{Binding FillPercentage}" />

这篇关于WPF 依赖属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!

本文标题为:WPF 依赖属性

基础教程推荐