如何正确公开内部控制的属性?

时间:2018-05-15 14:33:51

标签: c# wpf

我有一个名为CustomTreeView的自定义控件,其中包含TreeView。我想将SelectedItem的{​​{1}}属性公开给自定义控件的用户。

为此,我尝试将新的依赖项属性添加到自定义控件,并将该属性绑定到TreeView的{​​{1}}属性。

不幸的是,我似乎弄错了。你能看看吗?

TreeView.xaml

SelectedItem

TreeView.xaml.cs

TreeView

谢谢!

1 个答案:

答案 0 :(得分:1)

您的部分解决方案是in this answer here。它是一个只有链接的答案,带有死链接(或者是 - 我只是改进了它),但确实提到了关键点。

您无法绑定TreeView.SelectedItem。您的依赖项属性定义以多种方式中断,并且应根据标准WPF实践将其命名为SelectedItem。这里是后面的usercontrol代码,它定义了依赖属性以及事件处理程序作为绑定的替代。

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

    #region SelectedItem Property
    public Node SelectedItem
    {
        get { return (Node)GetValue(SelectedProperty); }
        set { SetValue(SelectedProperty, value); }
    }

    public static readonly DependencyProperty SelectedProperty =
        DependencyProperty.Register(nameof(SelectedItem), typeof(Node), typeof(CustomTreeView),
            new FrameworkPropertyMetadata(null,
                                          FrameworkPropertyMetadataOptions.BindsTwoWayByDefault,
                                          Selected_PropertyChanged)
            { DefaultUpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged });

    protected static void Selected_PropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        (d as CustomTreeView).OnSelectedChanged(e.OldValue);
    }

    private void OnSelectedChanged(object oldValue)
    {
        if (SelectedItem != treeView.SelectedItem)
        {
            var tvi = treeView.ItemContainerGenerator.ContainerFromItem(SelectedItem) as TreeViewItem;

            if (tvi != null)
            {
                tvi.IsSelected = true;
            }
        }
    }
    #endregion SelectedItem Property

    private void treeView_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
    {
        if (SelectedItem != e.NewValue)
        {
            SelectedItem = e.NewValue as Node;
        }
    }
}

这是UserControl XAML中的TreeView。我将ItemsSource和ItemTemplate省略为无关紧要。

<TreeView
    x:Name="treeView"
    SelectedItemChanged="treeView_SelectedItemChanged"
    />

这是我用来测试它的MainWindow.xaml的片段:

<StackPanel>
    <local:CustomTreeView x:Name="treeControl" />
    <Label 
        Content="{Binding SelectedItem.Text, ElementName=treeControl}"
        />
</StackPanel>

我的Node类具有Text属性,我通过DataContext填充树,以节省必须为项设置另一个依赖项属性。