WPF:具有依赖项属性和子控件的UserControl [英] WPF: UserControl with Dependency Property and sub-controls

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

问题描述

我正在尝试在WPF中创建自己的非常简单的Usercontrol。它基本上只是一个组合框,其中包含一些其他逻辑。
我尝试使用此教程创建自己的Depdency-Property: http://www.codeproject.com/Articles/140620/WPF-Tutorial-Dependency-Property

I'm trying to create my own, very simple, Usercontrol in WPF. It's basically just a Combobox, with some additional Logic in it. I tried to create my own Depdency-Property using this Tutorial: http://www.codeproject.com/Articles/140620/WPF-Tutorial-Dependency-Property

到目前为止,这种方法还可以,但是如果属性更改,我也想在用户控件的组合框中反映出来。看来我无法将子控件直接绑定到新的Dependency-Project。

This is working fine so far, but if the property changes, I'd like to reflect this on the Combobox in the User-Control as well. It seems like I can't bind the subcontrol directly to my new Dependency-Project.

此刻我的代码如下:

public partial class ClassSelector : UserControl
{
    public static readonly DependencyProperty CurrentValueProperty =
 DependencyProperty.Register("CurrentValue", typeof(ClassType),
 typeof(ClassSelector), new FrameworkPropertyMetadata());

    public ClassType CurrentValue
    {
        get
        {
            return  (ClassType)this.GetValue(CurrentValueProperty);
        }
        set
        {
            this.SetValue(CurrentValueProperty, value);
        }
    }

    public ClassSelector()
    {
        this.DataContext = this;
        InitializeComponent();
        cmbClassType.ItemsSource = Enum.GetValues(typeof(ClassType));
    }
}

设置依赖属性或组合框的值对我来说似乎很奇怪。
我试图通过以下方式将其直接绑定到xaml中:

Setting the value of the dependy-property or the Combobox seems weirds to me. I tried to bind it direclty in the xaml via:

<Grid>
    <ComboBox x:Name="cmbClassType" SelectedItem="{Binding Path=CurrentValue, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" SelectionChanged="cmbClassType_SelectionChanged" />
</Grid>

我尝试用组合框映射Dependicy-Project更改的事件,反之亦然,但这导致非常奇怪的代码,因为组合框的更改将不得不更改组合框的属性值和属性值。

I tried to map the Dependicy-Project changed Event with the combobox and visa versa, but this leads to very strange code, since the combobox change would have to change the property-value and the property-value the combobox.

我很确定一定有可能可以将DependencyProperty绑定到子控件,但是我找不到方法来完成这项工作。

I'm quite sure there has to be a possibility to bind a DependencyProperty to a subcontrol, but I can't find a way to make this work.

在此先感谢所有建议,并祝您周末愉快!

Thanks in advance for all advices guys and have a nice weekend

Matthias

Edith说:调用窗口需要将对象绑定到网格,而不是窗口。例如:

Edith says: The calling Window needs to bind the Object to the Grid, not to the Window, so for example:

grdMain.DataContext = new DeckSearch();

工作正常,同时

this.DataContext = new DeckSearch();

此行为仅在我的自定义控件上,所有其他控件与Window上的DataContext完美配合

This behavior is ONLY at my custom control, all other controls worked perfectly fine with the DataContext on the Window itself.

推荐答案

好的,在这里,我修复了您的代码,它在我的工作端正常工作

Okay so here I fixed your code and it is working at my end

UserControlCodeBehind

UserControlCodeBehind

public partial class ClassSelector : UserControl
{
    public static readonly DependencyProperty CurrentValueProperty = DependencyProperty.Register("CurrentValue", typeof(ClassType),
        typeof(ClassSelector), new FrameworkPropertyMetadata()
            {
                DefaultValue = ClassType.Type1,
                BindsTwoWayByDefault = true,
                PropertyChangedCallback = CurrentValueChanged,
                DefaultUpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged
            });


    private static void CurrentValueChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var obj = (ClassSelector)d;
        obj.cmbClassType.SelectedValue = e.NewValue;
    }

    public ClassType CurrentValue
    {
        get
        {
            return (ClassType)this.GetValue(CurrentValueProperty);
        }
        set
        {
            this.SetValue(CurrentValueProperty, value);
        }
    }

    public ClassSelector()
    {
        InitializeComponent();
        cmbClassType.ItemsSource = Enum.GetValues(typeof(ClassType));
        cmbClassType.SelectedValue = CurrentValue;
    }

}

UserControl的Xaml部分

The Xaml part of the UserControl

<Grid>
    <ComboBox x:Name="cmbClassType" SelectedValue="{Binding Path=CurrentValue}"/>
</Grid>

请检查它是否在您的终端工作。我没有添加任何额外的代码检查线程安全性和全部。

Please check if it is working at your end. I have not added any extra code checking for thread safety and all.

编辑

在我的解决方案中,当 CurrentValue Class Property 通知c $ c>更改。

In my solution I do get my Class Property notification when the CurrentValue changes.

下面是我的示例MainWindow代码。

Below is my sample MainWindow Code.

public partial class MainWindow : Window, INotifyPropertyChanged
{
    public MainWindow()
    {
        InitializeComponent();
        DataContext = this;
        Task.Run(() =>
            {
                Thread.Sleep(1000);
                Dispatcher.InvokeAsync(() =>
                    {
                        customCombobox.CurrentValue = ClassType.Type3;//Updating the UserControl DP
                    });
                Thread.Sleep(2000);
                this.CurrentValue = ClassType.Type2;//Updating my local Property
            });
    }

    private ClassType _currentValue;
    public ClassType CurrentValue
    {
        get { return _currentValue; }
        set
        {
            _currentValue = value;
            Debug.WriteLine("Value Changed to " + value.ToString());
            RaisePropertyChanged("CurrentValue");
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    void RaisePropertyChanged(string propName)
    {
        var pc = PropertyChanged;
        if (pc != null)
            pc(this, new PropertyChangedEventArgs(propName));
    }
}

还有我的MainWindow.xaml

And my MainWindow.xaml

<Window x:Class="WpfApplication.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:WpfApplication"
    Title="MainWindow" Height="250" Width="525">
<local:ClassSelector x:Name="customCombobox" Height="25" CurrentValue="{Binding CurrentValue}"/>
</Window>

这篇关于WPF:具有依赖项属性和子控件的UserControl的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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