WPF中的自定义模板注入

本文关键字:注入 自定义 WPF | 更新日期: 2023-09-27 18:25:08

我有以下XAML:

<ListView Name="_listView">
    <ListView.ItemTemplate>
        <DataTemplate>
            <Grid Name="_itemTemplate">
            </Grid>
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

我想得到的是在后台代码中创建一个属性,该属性将接受一个自定义用户控件并将其作为动态模板。类似这样的东西:

public UserControl ItemTemplate
{
    set { _itemTemplate.Content = value; }
}

然后我可以把我的控件放在窗口的XAML中,并像这样声明项模板:

<local:MyCustomControl ItemTemplate="local:ControlThatActsAsItemTemplate"/>

如何实现这样的睡眠?

WPF中的自定义模板注入

到目前为止,我已经找到了以下简单的解决方案。

在自定义控件XAML中定义ListBox:

<ListBox Name="_listBox"/>

在代码背后创建一个属性:

public DataTemplate ItemTemplate
{
    get { return _listBox.ItemTemplate; }
    set { _listBox.ItemTemplate = value; }
}

XAML中的父窗口或控件集中的资源:

<Window.Resources>
    <DataTemplate x:Key="CustomTemplate">
        <TextBlock Text="{Binding Path=SomeProperty}"/>
    </DataTemplate>
</Window.Resources>

然后声明自定义控件:

<local:CustomControl ItemTemplate="{StaticResource CustomTemplate}"/>

现在,您需要一个接口来公开SomeProperty和数据源,该接口由需要设置为_listBox.ItemsSource的接口实例组成。但这是另一回事。

使用依赖属性的解决方案。

在自定义UserControl中,声明将向_listBox:注入项模板的依赖属性

public static readonly DependencyProperty ItemTemplateProperty =
    DependencyProperty.Register("ItemTemplate",
                                typeof(DataTemplate),
                                typeof(AutoCompleteSearchBox),
                                new PropertyMetadata(ItemTemplate_Changed));
public DataTemplate ItemTemplate
{
    get { return (DataTemplate)GetValue(ItemTemplateProperty); }
    set { SetValue(ItemTemplateProperty, value); }
}
private static void ItemTemplate_Changed(
    DependencyObject d,
    DependencyPropertyChangedEventArgs e)
{
    var uc = (MyUserControl)d;
    uc._listBox.ItemTemplate = (DataTemplate)e.NewValue;
}

现在,您可以在托管窗口XAML中自由设置该属性的值:

<Window.Resources>
    <Style TargetType="local:MyUserControl">
        <Setter Property="ItemTemplate">
            <Setter.Value>
                <DataTemplate>
                    <StackPanel>
                        <TextBlock Text="{Binding Path=PropertyName}"/>
                    </StackPanel>
                </DataTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</Window.Resources>

UserControl中的_listBox将获得一个自定义ItemTemplate,它将响应您要设置为数据源的自定义接口或类。