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

C# 在代码隐藏中指定UserControl的.XAML部分,c#,wpf,xaml,code-behind,C#,Wpf,Xaml,Code Behind,我编写了自定义TreeView控件 XAML: 但当我尝试使用它时,我发现了一个众所周知的错误: 无法在元素“TextBox”上设置名称属性值“TextBox”TextBox'在元素“MyTreeView”的作用域下,该元素在另一个作用域中定义时已注册了名称 我找到了一些如何修复此错误的收据。也就是说,在其代码隐藏中指定控件的.xaml部分。 但我不知道我该怎么做 代码清楚地表明您想要扩展TreeView。基本上,如果您想要构建能够保存某些内容(可以命名为…)的控件,如ContentContro

我编写了自定义
TreeView
控件

XAML:

但当我尝试使用它时,我发现了一个众所周知的错误:

无法在元素“TextBox”上设置名称属性值“TextBox”TextBox'在元素“MyTreeView”的作用域下,该元素在另一个作用域中定义时已注册了名称

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

代码清楚地表明您想要扩展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();
    }
}
如果要自定义外观,应覆盖控件的默认样式。此样式应位于主题文件夹内的generic.xaml文件中。有关自定义控件开发的更多信息,请参阅


我找到了适合我的解决方案。这是如何在代码中而不是在
XAML
中定义
treevieItem
Style
的方法。现在我只在代码隐藏中定义了
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);
    }
}

已经有一个相同的。大多数答案也适用于你的情况。另外,您没有显示将
Name
设置为
TextBox
@ice的位置。我将
Name
设置为
TextBox
的位置并不重要。问题是“如何在其代码隐藏中指定控件的.xaml部分”。你能帮忙吗?@icebat我已经看到了这个问题,但我不明白在我的情况下,我应该用
OnInitialized
方法写什么……你看到问题是什么了吗?因为,你几乎只是复制粘贴了我的密码。您的代码是UserControl。我的代码是CustomControl。您的代码有部分类和XAML。我的代码从TreeView扩展了独立类。我的代码不会抛出名称范围错误。好的,我知道了,但是您的样式不包含
。这根绳子很重要。如果
Style
将与.cs分开定义,我将无法使用
EventSetter
,因为它需要事件处理程序。您可以使用OnLostFocus覆盖方法,而不是使用Eventhandler。只是不明白如何调用
OnLostFocus
方法,当
treevieItem
的LostFocus事件将上升时。它们之间的联系在哪里?
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();
    }
}
     <Style TargetType="{x:Type TreeViewItem}">
        <Setter Property="IsExpanded"
                Value="{Binding IsExpanded, Mode=TwoWay}" />
        <Setter Property="IsSelected"
                Value="{Binding IsSelected, Mode=TwoWay}" />
    </Style>
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);
    }
}