Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/13.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/sharepoint/4.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# WPF控件派生自标签:自定义属性(带DP)是否未使用setter?_C#_Wpf_Xaml_Mvvm_Dependency Properties - Fatal编程技术网

C# WPF控件派生自标签:自定义属性(带DP)是否未使用setter?

C# WPF控件派生自标签:自定义属性(带DP)是否未使用setter?,c#,wpf,xaml,mvvm,dependency-properties,C#,Wpf,Xaml,Mvvm,Dependency Properties,到目前为止,我的所有绑定都工作得很好,只要它们使用了现有的控件属性,比如按钮、标签等等。出于一个目的,我需要一个自定义画布(从画布继承)和一个附加属性。然而,在那里,绑定似乎不起作用。然后,我创建了一个更简单的示例,使用一个自定义标签可以重现我的问题。自定义标签在代码中定义如下: namespace CustomCanvasTest { class CustomLabel : Label { public string Str { get { return G

到目前为止,我的所有绑定都工作得很好,只要它们使用了现有的控件属性,比如按钮、标签等等。出于一个目的,我需要一个自定义画布(从画布继承)和一个附加属性。然而,在那里,绑定似乎不起作用。然后,我创建了一个更简单的示例,使用一个自定义标签可以重现我的问题。自定义标签在代码中定义如下:

namespace CustomCanvasTest
{
  class CustomLabel : Label
  {
    public string Str
    {
      get { return GetValue(StrProperty) as string; }
      set
      {
        SetValue(StrProperty, value);
      }
    }

    public static readonly DependencyProperty StrProperty =
      DependencyProperty.Register("Str", typeof(string), typeof(CustomLabel));
  }
}
主窗口的XAML:

<Window x:Class="CustomCanvasTest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:CustomCanvasTest"
        Title="MainWindow" Height="350" Width="525">
    <Window.DataContext>
        <local:ViewModel/>
    </Window.DataContext>
    <Grid>
        <Button Content="Button" HorizontalAlignment="Left" Margin="313,10,0,0" VerticalAlignment="Top" Width="75" Command="{Binding ButtonClickCmd}"/>
        <local:CustomLabel Content="{Binding SomeString}" Str="{Binding SomeString}" HorizontalAlignment="Left" Height="25" Margin="291,288,0,0" VerticalAlignment="Top" Width="176"/>
    </Grid>
</Window>
当我点击按钮时,标签内容会发生明显的变化,但是我在setter中为
Str
设置的断点永远不会到达。我在这里肯定犯了一些新手的错误,但即使环顾这里关于类似问题的其他答案,我也无法独自找出答案。提前谢谢你的帮助

来自MSDN上的文章:

出于实现的原因,在计算上降低了 将属性标识为依赖项属性并访问该属性 方法来设置它,而不是使用属性 包装器及其设置器。这是因为XAML处理器必须推断 支持代码的整个对象模型仅基于了解 结构所指示的类型和成员关系 标记和各种字符串

因为当前WPF实现的XAML处理器行为 因为属性设置完全绕过包装器,所以不应该 将任何附加逻辑放入包装器的集合定义中 您的自定义依赖项属性。如果你把这样的逻辑放在集合中 定义,则当属性为 在XAML中设置,而不是在代码中设置

因此,你的问题的答案是:不,不一定叫二传手


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

public static readonly DependencyProperty StrProperty =
    DependencyProperty.Register(
        "Str", typeof(string), typeof(CustomLabel),
        new PropertyMetadata(StrPropertyChanged));

private static void StrPropertyChanged(
    DependencyObject obj, DependencyPropertyChangedEventArgs e)
{
    var label = obj as CustomLabel;
    var str = e.NewValue as string;
    ...
}
用于获取分配给依赖项属性的值:

为在核心级别确实具有渲染/用户界面影响的非框架属性提供属性元数据

例如:

public class CustomLabel : Label
{
    public static readonly DependencyProperty StrProperty = 
                           DependencyProperty.Register("Str",
                                                       typeof(string),
                                                       typeof(CustomLabel), 
                                                       new UIPropertyMetadata(String.Empty, IsStrTurn));

    public string Str
    {
        get
        {
            return GetValue(StrProperty) as string; 
        }

        set
        {
            SetValue(StrProperty, value);
        }
    }

    private static void IsStrTurn(DependencyObject sender, DependencyPropertyChangedEventArgs e)
    {    
        string strOld = e.OldValue as string;
        string strNew = e.NewValue as string;

        System.Diagnostics.Debug.WriteLine("The old value is " + strOld); // The old value is "init"
        System.Diagnostics.Debug.WriteLine("The new value is " + strNew); // The new value is "blub"
    }
}

哇,谢谢,这就清楚了!但这让我陷入了一个不利的境地,因为我想在当前设置的属性(这将是一个自定义类,而不是字符串)中订阅一个事件,并且我想在setter中这样做。我无法在构造函数中执行此操作,因为该值可能尚未设置。你对此有什么建议吗?无论如何,非常感谢你的澄清!你可以注册一个。
public class CustomLabel : Label
{
    public static readonly DependencyProperty StrProperty = 
                           DependencyProperty.Register("Str",
                                                       typeof(string),
                                                       typeof(CustomLabel), 
                                                       new UIPropertyMetadata(String.Empty, IsStrTurn));

    public string Str
    {
        get
        {
            return GetValue(StrProperty) as string; 
        }

        set
        {
            SetValue(StrProperty, value);
        }
    }

    private static void IsStrTurn(DependencyObject sender, DependencyPropertyChangedEventArgs e)
    {    
        string strOld = e.OldValue as string;
        string strNew = e.NewValue as string;

        System.Diagnostics.Debug.WriteLine("The old value is " + strOld); // The old value is "init"
        System.Diagnostics.Debug.WriteLine("The new value is " + strNew); // The new value is "blub"
    }
}