在代码隐藏中指定UserControl的.XAML部分

时间:2014-11-28 07:45:29

标签: c# wpf xaml code-behind

我编写了自定义TreeView控件。

XAML:

<TreeView x:Class="EArchiveMaster.View.MyTreeView"
             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" 
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300">
    <TreeView.ItemContainerStyle>
        <Style TargetType="{x:Type TreeViewItem}">
            <Setter Property="IsExpanded" Value="{Binding IsExpanded, Mode=TwoWay}" />
            <Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay}" />
            <EventSetter Event="LostFocus" Handler="EventSetter_OnHandler" />
        </Style>
    </TreeView.ItemContainerStyle>
</TreeView>

的.cs

public partial class MyTreeView
{
    public event Action SomeItemLostFocus;

    public MyTreeView()
    {
        InitializeComponent();
    }

    private void EventSetter_OnHandler(object sender, RoutedEventArgs e)
    {
        e.Handled = true;
        if (SomeItemLostFocus != null)
            SomeItemLostFocus();
    }
}

但是当我尝试使用它时,我得知众所周知的错误:

无法设置名称属性值&#39; TextBox&#39;在元素&#39; TextBox&#39;。 &#39;文本框&#39;属于元素&#39; MyTreeView&#39;的范围,在另一个范围内定义时已经注册了名称。

我找到了一些收据如何修复此错误。即,在其代码隐藏中指定.xaml部分控件。 但我不知道我该怎么做。

2 个答案:

答案 0 :(得分:1)

代码清楚地表明您想要扩展TreeView。基本上,如果你想构建可以保存一些内容(可以命名为...)的控件,比如ContentControl,ItemsControl等,那么最好使用CustomControl。带有XAML和CS代码的UserControl不适合这种情况。

在您的情况下,创建一个类如下所示并扩展功能

public class MyTreeView : TreeView
{
    public event Action SomeItemLostFocus;

    public MyTreeView()
    {
        DefaultStyleKey = typeof(MyTreeView);
    }

    public override void OnLostFocus(object sender, RoutedEventArgs e)
    {
        e.Handled = true;
        if (SomeItemLostFocus != null)
            SomeItemLostFocus();
    }
}

如果要自定义外观,则应覆盖控件的默认样式。此样式应该在Themes文件夹中的generic.xaml文件中可用。有关自定义控件开发的更多信息是here

     <Style TargetType="{x:Type TreeViewItem}">
        <Setter Property="IsExpanded"
                Value="{Binding IsExpanded, Mode=TwoWay}" />
        <Setter Property="IsSelected"
                Value="{Binding IsSelected, Mode=TwoWay}" />
    </Style>

答案 1 :(得分:1)

我发现适合我的解决方案。这就是如何在代码中定义Style TreeViewItem的方式,而不是XAML。现在我TreeView仅在代码隐藏中定义,因此,错误不会上升。

public class MyTreeView : TreeView
{
    public event RoutedEventHandler ItemLostLogicFocus;

    protected override void OnInitialized(EventArgs e)
    {
        base.OnInitialized(e);

        var itemContainerStyle = new Style
        {
            TargetType = typeof(TreeViewItem),
        };

        #region Binding

        var expandedBinding = new Binding("IsExpanded")
        {
            Mode = BindingMode.TwoWay,
        };

        var selectedBinding = new Binding("IsSelected")
        {
            Mode = BindingMode.TwoWay,
        };

        #endregion

        #region Setters

        itemContainerStyle.Setters.Add(new Setter
        {
            Property = TreeViewItem.IsExpandedProperty,
            Value = expandedBinding
        });
        itemContainerStyle.Setters.Add(new Setter
        {
            Property = TreeViewItem.IsSelectedProperty,
            Value = selectedBinding
        });

        #endregion

        #region EventSetters

        itemContainerStyle.Setters.Add(new EventSetter
        {
            Event = LostFocusEvent,
            Handler = new RoutedEventHandler(ItemLostLogicFocusHandler)

        });

        #endregion

        ItemContainerStyle = itemContainerStyle;
    }

    private void ItemLostLogicFocusHandler(Object sender, RoutedEventArgs e)
    {
        e.Handled = true;
        if (ItemLostLogicFocus != null)
            ItemLostLogicFocus(sender, e);
    }
}