如何从子类中创建的依赖属性获取绑定数据

发布于 2025-01-09 05:11:40 字数 2733 浏览 4 评论 0原文

例如,在背景属性中,我们可以这样做

<cs:CustomControl.Background>
    <SolidColorBrush Color="{Binding BackGround}"/>
</cs:CustomControl.Background>

SolidColorBrush 是一个单独的类,包含单独的依赖属性,并且它工作正常,并且背景属性正在按预期更新。

我正在尝试在我的 CustomControl 上执行相同的概念。

我已经创建了一个具有这样的依赖属性的子类

public class SubClass : DependencyObject
{
    public double SubProperty1
    {
        get { return (double)GetValue(SubProperty1Property); }
        set { SetValue(SubProperty1Property, value); }
    }

    // Using a DependencyProperty as the backing store for SubProperty1.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty SubProperty1Property =
        DependencyProperty.Register("SubProperty1", typeof(double), typeof(SubClass), new PropertyMetadata(10.0d, OnSubProperty1Changed));

    private static void OnSubProperty1Changed(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        //never called;
    }

    public string SubProperty2
    {
        get { return (string)GetValue(SubProperty2Property); }
        set { SetValue(SubProperty2Property, value); }
    }

    // Using a DependencyProperty as the backing store for SubProperty1.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty SubProperty2Property =
        DependencyProperty.Register("SubProperty2", typeof(string), typeof(SubClass), new PropertyMetadata("test", OnSubProperty2Changed));

    private static void OnSubProperty2Changed(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        //never called;
    }
}

,在我的自定义工具的主类中,我创建了依赖属性,如下所示:

public SubClass MainProperty
{
    get { return (SubClass)GetValue(MainPropertyProperty); }
    set { SetValue(MainPropertyProperty, value); }
}

// Using a DependencyProperty as the backing store for MainProperty.  This enables animation, styling, binding, etc...
public static readonly DependencyProperty MainPropertyProperty =
        DependencyProperty.Register("MainProperty", typeof(SubClass), typeof(CustomControl), new PropertyMetadata((SubClass)null, OnMainPropertyChanged));

private static void OnMainPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
    // called when object created only and not called again when the property changed on the UI
}

然后在我的 WPF 窗口中,我按照以下方式进行了

<cs:CustomControl.MainProperty>
    <cs:SubClass SubProperty1="{Binding Length}" SubProperty2="{Binding Title}"/>
</cs:CustomControl.MainProperty>

代码编译,但依赖属性未更新,且回调函数在以下情况下未调用:视图模型更新

我怎样才能做到这一点?我想念什么 我希望有详细代码的任何想法 提前致谢

In background property for instance we can do like this

<cs:CustomControl.Background>
    <SolidColorBrush Color="{Binding BackGround}"/>
</cs:CustomControl.Background>

SolidColorBrush is a separate class and contains separate dependency properties, and it working fine and the background property is updating as expected.

I'm trying to do the same concept on my CustomControl.

I have create a subclass with dependency property like this

public class SubClass : DependencyObject
{
    public double SubProperty1
    {
        get { return (double)GetValue(SubProperty1Property); }
        set { SetValue(SubProperty1Property, value); }
    }

    // Using a DependencyProperty as the backing store for SubProperty1.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty SubProperty1Property =
        DependencyProperty.Register("SubProperty1", typeof(double), typeof(SubClass), new PropertyMetadata(10.0d, OnSubProperty1Changed));

    private static void OnSubProperty1Changed(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        //never called;
    }

    public string SubProperty2
    {
        get { return (string)GetValue(SubProperty2Property); }
        set { SetValue(SubProperty2Property, value); }
    }

    // Using a DependencyProperty as the backing store for SubProperty1.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty SubProperty2Property =
        DependencyProperty.Register("SubProperty2", typeof(string), typeof(SubClass), new PropertyMetadata("test", OnSubProperty2Changed));

    private static void OnSubProperty2Changed(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        //never called;
    }
}

And in my main class for my custom tool, I created dependency property as follows:

public SubClass MainProperty
{
    get { return (SubClass)GetValue(MainPropertyProperty); }
    set { SetValue(MainPropertyProperty, value); }
}

// Using a DependencyProperty as the backing store for MainProperty.  This enables animation, styling, binding, etc...
public static readonly DependencyProperty MainPropertyProperty =
        DependencyProperty.Register("MainProperty", typeof(SubClass), typeof(CustomControl), new PropertyMetadata((SubClass)null, OnMainPropertyChanged));

private static void OnMainPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
    // called when object created only and not called again when the property changed on the UI
}

Then in my WPF window I did as following

<cs:CustomControl.MainProperty>
    <cs:SubClass SubProperty1="{Binding Length}" SubProperty2="{Binding Title}"/>
</cs:CustomControl.MainProperty>

my code compiles but dependecy properties not updating and callback function not called when the viewmodel update

how can I make this work? and what do I miss
I hope there is any idea with detailed code
thanks in advance

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

那些过往 2025-01-16 05:11:40

在 Visual Studio 的输出窗口中,您应该看到类似的内容

System.Windows.Data 错误:2:找不到目标元素的管理 FrameworkElement 或 FrameworkContentElement。 ...

当您调试应用程序时。这是因为您的控件及其 DependencyObject 属性不形成逻辑树。

为了构建逻辑树,SubClass 必须从 Freezable 派生

public class SubClass : Freezable
{
   ...

    protected override Freezable CreateInstanceCore()
    {
        return new SubClass();
    }
}

,并且 CustomControl 必须将 SubClass 实例添加到其逻辑子集合中:

private static void OnMainPropertyChanged(
    DependencyObject o, DependencyPropertyChangedEventArgs e)
{
    if (e.OldValue != null)
    {
        ((CustomControl)o).RemoveLogicalChild(e.OldValue);
    }
    if (e.NewValue != null)
    {
        ((CustomControl)o).AddLogicalChild(e.NewValue);
    }
}

In the Output Window in Visual Studio you should have seen something like

System.Windows.Data Error: 2 : Cannot find governing FrameworkElement or FrameworkContentElement for target element. ...

when you debug your application. This is because your control and its DependencyObject property do not form a logical tree.

In order to build a logical tree, SubClass must derive from Freezable

public class SubClass : Freezable
{
   ...

    protected override Freezable CreateInstanceCore()
    {
        return new SubClass();
    }
}

and CustomControl must add SubClass instances to its logical children collection:

private static void OnMainPropertyChanged(
    DependencyObject o, DependencyPropertyChangedEventArgs e)
{
    if (e.OldValue != null)
    {
        ((CustomControl)o).RemoveLogicalChild(e.OldValue);
    }
    if (e.NewValue != null)
    {
        ((CustomControl)o).AddLogicalChild(e.NewValue);
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文