2017-07-16 31 views
0

在閱讀關於我注意到的數據模板時,您可以根據數據類型選擇不同的模板。 - 但是,也可以這樣做,針對不同的內容的數據?根據數據的功能/內容將數據綁定到不同的元素

我的模型視圖提供了一個數據列表,原則上它只是一個元組列表(綁定在自定義類中以便於打字)與Tuple<ImageData, AltText>。 類型的模型視圖的屬性是:

ReadOnlyObservableCollection<ThumbDispData> 

隨着ThumbDispData

public class ThumbDispData 
{ 
    public ImageData Idhl { get; set; } 
    public string AltText { get; set; } 
} 

現在我想顯示Image如果它能夠(ImageData.Source爲非null) - 否則它應該顯示的ALT文本。

的XAML或用戶控件:

<UserControl x:Class="test.ThumbPanel" 
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
      xmlns:test="clr-namespace:test" 
      mc:Ignorable="d" 
      d:DesignHeight="300" d:DesignWidth="300"> 
    <UserControl.Resources> 
     <DataTemplate DataType="{x:Type test:ThumbDispData}"> 
      <TextBlock Text="{Binding AltText}"></TextBlock> 
     </DataTemplate> 
    </UserControl.Resources> 
    <Grid Background="Transparent"> 
     <ItemsControl ItemsSource="{Binding}"> 
      <ItemsControl.ItemsPanel> 
       <ItemsPanelTemplate> 
        <WrapPanel IsItemsHost="True" /> 
       </ItemsPanelTemplate> 
      </ItemsControl.ItemsPanel> 
     </ItemsControl> 
    </Grid> 
</UserControl> 

遠高於只顯示ALT文本(工作):我將如何創建一個基於ThumbDispData內容的選擇。

回答

1

你可以使用一個DataTemplateSelector

<UserControl.Resources> 
    <DataTemplate x:Key="tt" DataType="{x:Type test:ThumbDispData}"> 
     <TextBlock Text="{Binding AltText}"></TextBlock> 
    </DataTemplate> 
    <DataTemplate x:Key="img" DataType="{x:Type test:ThumbDispData}"> 
     <Image Source="{Binding Idhl}" /> 
    </DataTemplate> 
    <local:Selector x:Key="selector" TextTemplate="{StaticResource tt}" ImageTemplate="{StaticResource img}" /> 
</UserControl.Resources> 
<Grid Background="Transparent"> 
    <ItemsControl ItemsSource="{Binding}" ItemTemplateSelector="{StaticResource selector}"> 
     <ItemsControl.ItemsPanel> 
      <ItemsPanelTemplate> 
       <WrapPanel IsItemsHost="True" /> 
      </ItemsPanelTemplate> 
     </ItemsControl.ItemsPanel> 
    </ItemsControl> 
</Grid> 

public class Selector : DataTemplateSelector 
{ 
    public DataTemplate ImageTemplate { get; set; } 
    public DataTemplate TextTemplate { get; set; } 

    public override DataTemplate SelectTemplate(object item, DependencyObject container) 
    { 
     ThumbDispData data = item as ThumbDispData; 
     if (data != null && data.Idhl != null) 
      return ImageTemplate; 


     return TextTemplate; 
    } 
} 
0

我會根據ThumbDispData的內容創建一個選擇器。

你通常會寫的DataTemplateSelector一個子類,在您檢查Idhl財產,並返回取決於它是否是空或不是一個不同的模板對象。通常,模板將是一個資源,您可以在選擇器中動態加載。

但是您的場景很簡單,我會使用樣式代替。例如:

<DataTemplate DataType="{x:Type test:ThumbDispData}" 
    xmlns:p="http://schemas.microsoft.com/winfx/2006/xaml/presentation"> 
    <Grid> 
    <TextBlock Text="{Binding AltText}"> 
     <TextBlock.Style> 
     <p:Style TargetType="TextBlock"> 
      <Setter Visibility="Visible"/> 
      <p:Style.Triggers> 
      <DataTrigger Binding="{Binding Idhl}" Value="{x:Null}"> 
       <Setter Visibility="Collapsed"/> 
      </DataTrigger> 
      </p:Style> 
     </p:Style> 
     </TextBlock.Style> 
    </TextBlock> 
    <Image Source="{Binding Idhl}"> 
     <Image.Style> 
     <p:Style TargetType="Image"> 
      <Setter Visibility="Collapsed"/> 
      <p:Style.Triggers> 
      <DataTrigger Binding="{Binding Idhl}" Value="{x:Null}"> 
       <Setter Visibility="Visible"/> 
      </DataTrigger> 
      </p:Style> 
     </p:Style> 
     </Image.Style> 
    </Image> 
    </Grid> 
</DataTemplate> 

注:

  • 嚴格地說,你不需要在TextBlock風格<Setter Visibility="Visible"/>,因爲這是默認值。我把它放在那裏,因爲它有助於記錄兩個元素的風格之間的對稱性。
  • xmlns:p聲明僅作爲堆棧溢出解決方法,因爲XML格式化程序在其他情況下不會正確處理XAML Style元素。在真正的XAML中,您可以將其保留,直接使用Style名稱而不是p:Style
+0

我有這樣的做法最大的問題是要三思而後它看起來。圖像數據本質上是不穩定的(源可能已損壞/表示Image類無法顯示的格式),所以當且僅當'Image'可以顯示源時,沒有數據觸發的方式嗎? – paul23

+0

_「是否有數據觸發的方法當且僅當圖像可以顯示源?」 - 當然是。但是你的問題沒有提供足夠的背景來提供一個具體的例子。你會注意到,上面的例子甚至沒有考慮到你正在使用一些用戶定義的類型'ImageData'作爲屬性。我懷疑你真正的代碼會直接綁定到'Idhl',因爲你似乎已經將圖像源換成了其他類型。 –

+0

但基本的想法是一樣的;在_some_屬性上觸發_does_指示數據是否有效,並將Source屬性綁定到有效的圖像源(當數據無效時,大概爲null)。 –

相關問題