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);
}
}