我有一组带有附加命令和逻辑的控件,它们经常以相同的方式重用。我决定创建一个包含所有公共控件和逻辑的用户控件。
然而,我也需要控件能够容纳可以命名的内容。我尝试了以下几种方法:
<UserControl.ContentTemplate>
<DataTemplate>
<Button>a reused button</Button>
<ContentPresenter Content="{TemplateBinding Content}"/>
<Button>a reused button</Button>
</DataTemplate>
</UserControl.ContentTemplate>
但是,似乎放在用户控件中的任何内容都不能命名。例如,如果我以以下方式使用控件:
<lib:UserControl1>
<Button Name="buttonName">content</Button>
</lib:UserControl1>
我收到以下错误:
无法对元素“Button”设置名称属性值“”buttonName“”。“”“‘Button”位于元素“UserControl1”的作用域中,该元素在另一个作用域中定义时已注册了一个名称。
如果我删除了buttonName,它就会编译,但是我需要能够命名内容。我如何才能做到这一点?
发布于 2009-04-16 19:58:03
当使用XAML时,这似乎是不可能的。当我实际拥有所需的所有控件时,自定义控件似乎有点夸张,但只需要用一点逻辑将它们组合在一起,并允许命名内容。
正如mackenir建议的那样,JD's blog上的解决方案似乎有最好的折衷方案。扩展JD的解决方案以允许控件仍然在XAML中定义的一种方法可能如下所示:
protected override void OnInitialized(EventArgs e)
{
base.OnInitialized(e);
var grid = new Grid();
var content = new ContentPresenter
{
Content = Content
};
var userControl = new UserControlDefinedInXAML();
userControl.aStackPanel.Children.Add(content);
grid.Children.Add(userControl);
Content = grid;
}
在上面的示例中,我创建了一个名为UserControlDefinedInXAML的用户控件,它的定义类似于任何使用XAML的普通用户控件。在我的UserControlDefinedInXAML中,我有一个名为aStackPanel的StackPanel,我希望在其中显示我命名的内容。
发布于 2010-08-05 17:28:49
答案是不要使用UserControl来做这件事。
创建一个扩展ContentControl的类
public class MyFunkyControl : ContentControl
{
public static readonly DependencyProperty HeadingProperty =
DependencyProperty.Register("Heading", typeof(string),
typeof(MyFunkyControl), new PropertyMetadata(HeadingChanged));
private static void HeadingChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
((MyFunkyControl) d).Heading = e.NewValue as string;
}
public string Heading { get; set; }
}
然后使用样式指定内容
<Style TargetType="control:MyFunkyControl">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="control:MyFunkyControl">
<Grid>
<ContentControl Content="{TemplateBinding Content}"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
最后--使用它
<control:MyFunkyControl Heading="Some heading!">
<Label Name="WithAName">Some cool content</Label>
</control:MyFunkyControl>
发布于 2011-08-24 04:11:00
我使用的另一个替代方法是只在Loaded
事件中设置Name
属性。
在我的例子中,我有一个相当复杂的控件,我不想在代码隐藏中创建它,它为某些行为寻找具有特定名称的可选控件,因为我注意到可以在DataTemplate
中设置名称,所以我想我也可以在Loaded
事件中这样做。
private void Button_Loaded(object sender, RoutedEventArgs e)
{
Button b = sender as Button;
b.Name = "buttonName";
}
https://stackoverflow.com/questions/751325
复制相似问题