2013-03-20 69 views
2

我希望能夠根據ViewModel中的屬性更改我的自定義班級正在使用的DataTemplate如何根據ViewModel屬性更改自定義類型的DataTemplate?

我找不到任何明顯的例子,我覺得我可能不夠了解WPFXAML知道這甚至有可能。

我的ViewModel屬性表示用戶是否摺疊了應用程序一側的列。如果列被瓦解了,我想只顯示圖像的每個用戶,如果柱擴大,我將展示在StackPanel照片,名字和姓氏。

我覺得有一些真正基本的東西,我只是不明白,我想我正在尋找一個人可能嘗試過這樣的事情,或知道如何以正確的方式做到這一點。

User.cs

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

我使用的是ObservableCollection<User>握着我的視圖模型User對象的集合。 我想使用的2個DataTemplates。 (現在我只使用一個默認的圖像和文字來看看它的樣子)

的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

<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

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

上DataTemplateSelector閱讀起來,這裏有一個很好的例子http://tech.pro/tutorial/807/wpf-tutorial-how-to-use- a-datatemplateselector – Phil 2013-03-20 19:50:14

+0

@Phil是的,如果你有一個特定於我的需求的例子,* ViewModel *中的一個屬性,而不是模型本身,那麼通過一切手段,鏈接走。 http://tech.pro/tutorial/807/wpf-tutorial-how-to-use-a-datatemplateselector是我通過嘗試弄清楚DataTemplateSelector是否是我需要的,並發現它不起作用我的情況AFAIK。 – Zack 2013-03-20 19:52:17

+0

鏈接中的示例爲您提供了所需的所有信息。看看他的自定義datatemplateselector類,他正在接受一個項目對象並將其轉換爲字符串。如果您不使用字符串,則將其轉換爲適當的對象,這將是您的視圖模型。然後編寫你的邏輯,比較viewmodel上的屬性並返回相應的數據模式 – failedprogramming 2013-03-20 20:15:12

回答

0

我以爲這個問題。如果我需要根據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> 

轉換

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(); 
    } 
} 
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> 

和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; } 
} 
相關問題