在 UserControl 中为 ListView 添加 DataTemplate

Add a DataTemplate for a ListView in an UserControl

我在 WPF 中有一个简单的用户控件,它包含一些按钮、文本框和一个列表视图。我稍微简化了那个控件:

<UserControl x:Class="Example.SearchListControl"
         ...
         mc:Ignorable="d">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="*" />
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>

        <TextBox Grid.Row="0" Text="{Binding SearchText, UpdateSourceTrigger=PropertyChanged}" />
        <ListView Grid.Row="1" ItemsSource="{Binding Items}" SelectedItem="{Binding Current}" />
        <Button Grid.Row="2" Command="{Binding SomeSortOfCommand}">
   </Grid>
</UserControl>

该用户控件的 ViewModel 如下所示:

public class SearchListViewModel<T> : ViewModelBase
{
    private ObservableCollection<T> _items;

    public ObservableCollection<T> Items
    {
        get
        {
            return _items;
        }
        set
        {
            _items = value;
            OnPropertyChanged();
        }
    }

    private T _current;

    public T Current
    {
        get
        {
            return _current;
        }
        set
        {
            _current = value;
            OnPropertyChanged();
        }
    }

    ...
}

我把那个控件放在另一个 window 中,就像那样:

<Window x:Class="Example.TestWindow"
        ...>

    <Grid>
        <local:SearchListControl DataContext="{Binding GenericSearchListViewModel}" />
    </Grid>
</Window>

为了更灵活,我想在 window 的那个控件中为 ListView 设置数据模板?类似于:

<Window ...>

    <Window.Resources>
        <DataTemplate x:Key="ListViewTemplate">
            <Grid>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="100" />
                    <ColumnDefinition Width="*" />
                </Grid.ColumnDefinitions>
                <TextBlock Grid.Column="0" Text="{Binding Path=ShortCaption}" />
                <TextBlock Grid.Column="1" Text="{Binding Path=Caption}" />
            </Grid>
        </DataTemplate>

    </Window.Resources>
    <Grid>
        <local:SearchListControl DataContext="{Binding GenericSearchListViewModel}" 
              DataTemplate="{StaticResource ListViewTemplate}" />
    </Grid>
</Window>

这可能吗,还是我走的路完全错了?

如果您在 SearchListUserControl.xaml 文件中为 ListView 命名:

<ListView x:Name="lv" ... />

...您可以通过 SearchListControl 属性 轻松公开其 ItemTemplate 属性 class:

public abstract class SearchListControl : UserControl
{
    public SearchListControl()
    {
        InitializeComponent();
    }

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

...并从 window:

进行设置
<local:SearchListControl DataContext="{Binding GenericSearchListViewModel}" 
          DataTemplate="{StaticResource ListViewTemplate}" /