Con*_*ngo 0 wpf xaml datatemplate wpf-controls contenttemplate
我有这个 XAML:
<dxb:BarStaticItem>
<TextBlock Text="{Binding MyStatusBarText}"></TextBlock>
</dxb:BarStaticItem>
Run Code Online (Sandbox Code Playgroud)
但是,我收到此错误:
Cannot add content to an object of type BarStaticItem
我该如何解决这个问题,以便我可以执行诸如更改渲染项目的颜色和样式之类的操作?
假设BarStaticItem是一个UserControl...
我在一个部分cs文件中使用代码,其中(几乎)所有事情都已完成,用一个ObservableCollectionofUIElement代替(或任何你想要的元素)
1)创建一个名为 的相关分部类BarStaticItem.Children.cs,然后添加所需的命名空间:
using System.Collections.ObjectModel; // ObservableCollection.
using System.Collections.Specialized; // NotifyCollectionChangedEventHandler.
using System.Windows.Markup; // [ContentProperty()]
Run Code Online (Sandbox Code Playgroud)
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; }
}
}
Run Code Online (Sandbox Code Playgroud)
3) 现在在 cs 文件中的私有方法中创建 ObservableCollection 属性初始值设定项:
private void RegisterChildrenObservation()
{
Children = new ObservableCollection<UIElement>();
Children.CollectionChanged +=
new NotifyCollectionChangedEventHandler(Children_CollectionChanged);
}
Run Code Online (Sandbox Code Playgroud)
4) 在自定义 UI 元素的构造函数中调用该初始值设定项:
namespace YourNamespace.SubNamespace
{
public partial class BarStaticItem : UserControl
// (This is the base BarStaticItem.xaml.cs file)
{
public BarStaticItem()
{
InitializeComponent();
RegisterChildrenObservation(); // <- here !
}
}
}
Run Code Online (Sandbox Code Playgroud)
5)通过声明在初始化程序中调用的方法处理程序来处理 BarStaticItem.Children.cs 文件中 Children 集合的行为:
这只是简单的正式程序。一旦您理解了整个事情,您就会发现您可以使用它并创建比单独使用 xaml 能做的更多的场景。首先,这里只有两个状态真正重要:
NotifyCollectionChangedAction.AddNotifyCollectionChangedAction.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;
}
}
}
Run Code Online (Sandbox Code Playgroud)6) 您即将完成,但您必须在 BarStaticItem.xaml 文件中创建并命名一个 UIElement 以包含添加的 UIElements :
<UserControl ...>
<Grid
x:Name="MyChildContainer"><!-- HERE ! -->
</Grid>
</UserControl>
Run Code Online (Sandbox Code Playgroud)
然后就完成了,您可以像您一样直接在 XAML 中将任何子元素添加到 BarStaticItem 中。
<dxb:BarStaticItem>
<TextBlock Text="{Binding MyStatusBarText}"></TextBlock>
</dxb:BarStaticItem>
Run Code Online (Sandbox Code Playgroud)
..这TextBlock将落在.中Grid定义和命名的位置。您可以使用 DockPanel 或 StackPanel,甚至可以根据子元素的类型或更新(依赖项)属性来决定子元素将进入哪个容器,例如:MyChildContainerBarStaticItem.xamlNotifyCollectionChangedAction.Add
private void Children_CollectionChanged(
object sender, NotifyCollectionChangedEventArgs e)
{
switch (e.Action)
{
case NotifyCollectionChangedAction.Add:
{
foreach (UIElement currentElement in e.NewItems)
{
if (currentElement.GetType() == typeof(TextBlock))
{
TextBlock currentTextBlock = (TextBlock)currentElement;
// Manipulate your TextBlock...
HeaderTextBlockContainer.Children.Add(currentElement);
}
else if (currentElement.GetType() == typeof(Button))
{
FooterButtonsDockPanel.Children.Add(currentElement);
DockPanel.SetDock(currentElement, Dock.Right);
}
else
{
MainContentContainer.Children.Add(currentElement);
}
ContentDefined = true; // Custom Property.
}
//...
Run Code Online (Sandbox Code Playgroud)
谁DV你不是我
| 归档时间: |
|
| 查看次数: |
6407 次 |
| 最近记录: |