如何根据ViewModel属性更改自定义类型的DataTemplate

本文关键字:自定义 类型 DataTemplate 何根 ViewModel 属性 | 更新日期: 2023-09-27 18:04:51

我想能够改变我的自定义类正在使用的DataTemplate,基于ViewModel中的属性。

我找不到任何明确的例子,我觉得我可能对WPFXAML不够了解,无法知道这是否可能。

我的ViewModel属性表示用户是否在应用程序的一侧折叠了一个列。如果列折叠,我希望只显示每个用户的图像,如果列展开,我将在StackPanel中显示图片、名字和姓氏。

我觉得有一些非常基本的东西我只是不理解,我想我正在寻找一个可能尝试过这样的东西或知道如何正确地做这件事的人。

<标题> User.cs h1> 使用ObservableCollection<User>来保存视图模型中User对象的集合。我的2个datatemplate,我想使用。(现在我只是使用默认的图像和文本来看看它的样子) <标题> DataTemplates h1> 试着写一个样式,并应用到我的ItemsControl在视图中,我试着写一个数据模板,使用触发器来决定使用哪个模板,但我不能完全弄清楚我在哪里出错。 <标题> 风格
<Style x:Key="userTemplateStyle" TargetType="ItemsControl">
  <Setter Property="ItemTemplate" Value="{StaticResource UserExpanded}"/>
  <Style.Triggers>
    <DataTrigger Binding="{Binding ColumnIsCollapsed, Source={StaticResource ViewModel}}" Value="True">
      <Setter Property="ItemTemplate" Value="{StaticResource UserCollapsed}"/>
    </DataTrigger>
  </Style.Triggers>
</Style>

当我在XAML中添加ItemsControl的Style属性时,我得到以下异常。

<标题>异常h1> DataTemplate,我试图使用作为ItemsControl的ItemTemplate。(我觉得这是错误的方式去做,但我还是尝试了) <标题> DataTemplate h1> ItemsControl h1> div class="answers">

你的代码对我来说很好…

<Window x:Class="WpfApplication8.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:WpfApplication8="clr-namespace:WpfApplication8"
    Title="MainWindow"
    Width="525"
    Height="350">
<Window.Resources>
    <WpfApplication8:ViewModel x:Key="ViewModel" />
    <DataTemplate x:Key="UserCollapsed" />
    <DataTemplate x:Key="UserExpanded">
        <StackPanel Width="200"
                    Height="200"
                    Background="Red">
            <TextBlock Text="Firstname" />
            <TextBlock Text="Lastnamehere" />
        </StackPanel>
    </DataTemplate>
    <Style x:Key="userTemplateStyle" TargetType="ItemsControl">
        <Setter Property="ItemTemplate" Value="{StaticResource UserExpanded}" />
        <Style.Triggers>
            <DataTrigger Binding="{Binding ColumnIsCollapsed, Source={StaticResource ViewModel}}" Value="True">
                <Setter Property="ItemTemplate" Value="{StaticResource UserCollapsed}" />
            </DataTrigger>
        </Style.Triggers>
    </Style>
</Window.Resources>
<Grid x:Name="grid" DataContext="{StaticResource ViewModel}">
    <ItemsControl Name="itcLoggedInUsers"
                  Grid.Row="1"
                  Margin="0"
                  BorderThickness="0"
                  ItemsSource="{Binding LoggedInUsers}"
                  Style="{StaticResource userTemplateStyle}" />
</Grid>

和ViewModel

  public class ViewModel: INotifyPropertyChanged
{
    private bool _columnIsCollapsed;
    public ViewModel()
    {
        ColumnIsCollapsed = false;
        LoggedInUsers = new ObservableCollection<User>();
        LoggedInUsers.Add(new User(){FirstName = "SSSSSS", LastName = "XXXXXX"});
    }
    public bool ColumnIsCollapsed
    {
        get { return _columnIsCollapsed; }
        set
        {
            _columnIsCollapsed = value;
            OnPropertyChanged(new PropertyChangedEventArgs("ColumnIsCollapsed"));
        }
    }
    public ObservableCollection<User> LoggedInUsers { get; set; }
    public event PropertyChangedEventHandler PropertyChanged;
    public void OnPropertyChanged(PropertyChangedEventArgs e)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null) handler(this, e);
    }
}
public class User
{
    public string ImageFile { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

如何根据ViewModel属性更改自定义类型的DataTemplate

我仔细考虑了这个问题。如果我需要基于ViewModelboolean属性在DataTemplate中显示或隐藏一个元素,我可以将元素的可见性绑定到ViewModel的属性上,并使用转换器返回可见性。

<标题> 解决方案
<DataTemplate DataType="{x:Type md:User}">
  <StackPanel>
    <Image Source="/Images/anon.png" 
           Height="50" 
           Width="50"
           Margin="0,5,0,0"/>
    <TextBlock Text="Firstname" Visibility="{Binding ColumnIsCollapsed, Source={StaticResource ViewModel},Converter={StaticResource InvertBoolVisibility}}"/>
    <TextBlock Text="Lastnamehere" Visibility="{Binding ColumnIsCollapsed, Source={StaticResource ViewModel},Converter={StaticResource InvertBoolVisibility}}"/>
  </StackPanel>
</DataTemplate>
<标题>转换器h1> /html>