3

DataTemplateのプロパティに基づいて、カスタム クラスが使用しているを変更できるようにしたいと考えていViewModelます。

WPF明確な例を見つけることができず、これが可能かどうかについて十分に知らない、または知ることができないように感じXAMLます。

私のViewModelプロパティは、ユーザーがアプリケーションの片側で列を折りたたんだかどうかを表します。列が折りたたまれている場合は、各ユーザーの画像のみを表示したいと思います。列が展開されている場合は、写真、姓名をStackPanel.

私はまだ理解していない本当に基本的な何かがあるように感じます。おそらく、このようなことを試した人、またはこれを正しい方法で行う方法を知っている人を探していると思います.

ユーザー.cs

public class User
{
  public string ImageFile {get; set;}
  public string FirstName {get; set;}
  public string LastName {get; set;}
}

ビューモデルにオブジェクトObservableCollection<User>のコレクションを保持するためにを使用しています。User使用したい2つのDataTemplates。(現在、デフォルトの画像とテキストを使用してどのように見えるかを確認しています)

データテンプレート

<DataTemplate x:Key="UserCollapsed">
  <Image Source="/Images/anon.png" 
         Height="50" 
         Width="50"
         Margin="0,5,0,0"/>
</DataTemplate>

<DataTemplate x:Key="UserExpanded">
  <StackPanel>
    <Image Source="/Images/anon.png" 
           Height="50" 
           Width="50"
           Margin="0,5,0,0"/>
     <TextBlock Text="Firstname"/>
     <TextBlock Text="Lastnamehere"/>
   </StackPanel>
 </DataTemplate>

スタイルを作成して、それをビューの 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 プロパティを追加すると、次の例外が発生します。

例外

{"Unable to cast object of type 'MS.Internal.NamedObject' to type 'System.Windows.DataTemplate'."}

そして、ItemsControlのItemTemplateとして使用しようとしたDataTemplate。(これは間違った方法だと思いますが、とにかく試しました)

データテンプレート

<DataTemplate DataType="{x:Type md:CUser}">
  <DataTemplate.Triggers>
    <DataTrigger Binding="{Binding ColumnIsCollapsed, Source={StaticResource ViewModel}}" Value="True">
      <Setter Property="DataTemplate" Value="{StaticResource UserCollapsed}"/>
    </DataTrigger>
  </DataTemplate.Triggers>
</DataTemplate>

アイテムコントロール

<ItemsControl Visibility="{Binding ColumnVisibility}"
  Style="{StaticResource userTemplateStyle}"
  BorderThickness="0"
  Name="itcLoggedInUsers"
  Margin="0"
  ItemsSource="{Binding LoggedInUsers}"
  Grid.Row="1"/>
4

2 に答える 2

0

あなたのコードは私にとってはうまくいきます...

<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>

そしてビューモデル

  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; }
}
于 2013-03-20T20:13:41.917 に答える
0

私はこの問題を考えすぎました。のプロパティにDataTemplate基づいての要素を表示または非表示にする必要がある場合は、要素の可視性を のプロパティにバインドし、コンバーターを使用して可視性を返すことができます。booleanViewModelViewModel

解決

<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>

コンバータ

public class InvertBoolToVisibilityConverter : IValueConverter
{
  public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
  {
    var theBool = (bool)value;
    if (theBool)
      return Visibility.Collapsed;
    else
      return Visibility.Visible;
  }

  public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
  {
    throw new NotImplementedException();
  }
}
于 2013-03-20T20:56:31.763 に答える