我有这个XAML:
<dxb:BarStaticItem>
<TextBlock Text="{Binding MyStatusBarText}"></TextBlock>
</dxb:BarStaticItem>
但是,我收到了这个错误:
Cannot add content to an object of type BarStaticItem
如何修复此问题,以便我可以更改渲染项目的颜色和样式等内容?
答案 0 :(得分:4)
假设BarStaticItem
是UserControl
...
我在一个部分cs文件中使用了代码,其中(几乎)所有内容都已完成,ObservableCollection
代替UIElement
(或您想要的任何元素)
1)创建一个名为BarStaticItem.Children.cs
的相关部分类,然后添加所需的名称空间:
using System.Collections.ObjectModel; // ObservableCollection.
using System.Collections.Specialized; // NotifyCollectionChangedEventHandler.
using System.Windows.Markup; // [ContentProperty()]
2)在部分类声明上方添加ContentProperty
标记,然后添加Children
属性声明:
namespace YourNamespace.SubNamespace
{
[ContentProperty("Children")] // <- here !
public partial class BarStaticItem
// (This is the related BarStaticItem.Children.cs file)
{
/// <summary>
/// Gets the Children Property of this BarStaticItem.
/// </summary>
public ObservableCollection<UIElement> Children { get; private set; }
}
}
3)现在在cs文件的私有方法中创建ObservableCollection属性初始值设定项:
private void RegisterChildrenObservation()
{
Children = new ObservableCollection<UIElement>();
Children.CollectionChanged +=
new NotifyCollectionChangedEventHandler(Children_CollectionChanged);
}
4)在自定义UI元素的构造函数中调用该初始值设定项:
namespace YourNamespace.SubNamespace
{
public partial class BarStaticItem : UserControl
// (This is the base BarStaticItem.xaml.cs file)
{
public BarStaticItem()
{
InitializeComponent();
RegisterChildrenObservation(); // <- here !
}
}
}
5)通过声明在初始化程序中调用的方法处理程序,处理BarStaticItem.Children.cs文件中的Children集合的行为:
这只是简单的正式程序。一旦你了解了整个事情,你就会发现你可以使用它并创建比你单独使用xaml更多的场景。首先,这里只有两个州非常重要:
NotifyCollectionChangedAction.Add
NotifyCollectionChangedAction.Remove
private void Children_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
switch (e.Action)
{
case NotifyCollectionChangedAction.Add:
{
foreach (UIElement currentElement in e.NewItems)
{
MyChildContainer.Children.Add(currentElement);
}
break;
}
case NotifyCollectionChangedAction.Move:
{
break;
}
case NotifyCollectionChangedAction.Remove:
{
foreach (UIElement currentElement in e.OldItems)
{
MyChildContainer.Children.Remove(currentElement);
}
break;
}
case NotifyCollectionChangedAction.Replace:
{
break;
}
case NotifyCollectionChangedAction.Reset:
{
break;
}
default:
{
break;
}
}
}
6)您已接近完成,但您必须在BarStaticItem.xaml文件中创建并命名UIElement以包含添加的UIElements:
<UserControl ...>
<Grid
x:Name="MyChildContainer"><!-- HERE ! -->
</Grid>
</UserControl>
然后你就完成了,你可以直接在XAML中向你的BarStaticItem添加任何子元素,就像你一样。
<dxb:BarStaticItem>
<TextBlock Text="{Binding MyStatusBarText}"></TextBlock>
</dxb:BarStaticItem>
..并且TextBlock
将落在Grid
中定义并命名为MyChildContainer
的{{1}}。您可以使用DockPanel或StackPanel,甚至根据{Element}中的类型或更新(依赖关系)属性决定子元素将在哪个容器中运行,如:
BarStaticItem.xaml
你是谁DV你不是我
答案 1 :(得分:-1)
这个XAML可以正常工作,但是它的限制(它不允许你按要求设置显示文本的颜色):
<dxb:BarStaticItem
Content="{Binding MyStatusBarText}">
</dxb:BarStaticItem>
此特定控件允许我们设置ContentTemplate
。我们可以使用它来设置内容的样式:
<dxb:BarStaticItem
ContentTemplate="????">
</dxb:BarStaticItem>
首先,我们在DataTemplate
中定义Window.Resources
。这就是我们的ContentTemplate
将指出的内容:
<Window.Resources>
<DataTemplate x:Key="MyStatusBarContentTemplate">
<!-- As the DataContext of a resource does not default to the window, we have to use RelativeSource to find the window. -->
<TextBlock Name="MyText"
Text="{Binding Path=MyStatusBarText,
RelativeSource={RelativeSource Mode=FindAncestor,
AncestorType=Window}}">
</TextBlock>
</DataTemplate>
</Window.Resources>
由于DataContext
的{{1}}与XAML的其余部分不同,如果省略XAML DataTemplate
,则绑定将无法正常工作。除此之外,我们所做的只是定义一个模板,该模板可用于呈现控件的内容。
然后,我们将控制权指向RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window}
:
DataTemplate
现在我们已经定义了自定义数据模板,我们可以做任何我们想做的事情。例如,我们可以添加一个<dxb:BarStaticItem
ContentTemplate="{DynamicResource MyStatusBarContentTemplate}">
</dxb:BarStaticItem>
,如果状态栏包含文本Converter
(其他情况不可能,则为蓝色)。
此答案还说明了如何使用Error
显示大多数控件的自定义内容。
<强>更新强>
不是在Window的资源中定义DataTemplate
,而是将其定义为DataTemplate
的资源。这会将相关项目保存在XAML中。
这个特殊的XAML意味着如果文本包含字符串BarStaticItem
,状态栏文本会自动变为红色,状态栏文本会自动加上时间前缀。如果您希望我发布转换器的C#代码,请告诉我。
Error