2013-10-22 64 views
0

我不知道如何手動觸發模板選擇器(單擊按鈕時)。在加載時使用Template1,但想在使用Temaplte2進行btn時更改。有沒有類似OnPorpertyChanged?觸發項目模板選擇器更改

我reffering到 <ItemsControl x:Name="OptionItemsControl" ItemTemplateSelector="{StaticResource optionItemTemplateSelector}" - 我想觸發ItemTemplateSelector變化......

<!-- BODY (elements)--> 
     <FlipView x:Name="OptionPagesFlipView" Grid.Row="1" TabNavigation="Cycle" SelectionChanged="OptionPagesFlipView_SelectionChanged" ItemsSource="{Binding OptionsPageItems}"> 
      <FlipView.ItemTemplate> 
       <DataTemplate x:Name="OptionMonthPageTemplate"> 
        <ScrollViewer x:Name="OptionsScrollViewer" HorizontalScrollMode="Disabled" HorizontalAlignment="Stretch" VerticalScrollBarVisibility="Auto"> 
         <Grid> 
          <ItemsControl x:Name="OptionItemsControl" ItemTemplateSelector="{StaticResource optionItemTemplateSelector}" ItemsSource="{Binding OptionItems, Mode=OneWay}" Visibility="{Binding OptionsPageVisibility}">         
          </ItemsControl> 
          <Grid x:Name="LoadingGrid" HorizontalAlignment="Center" VerticalAlignment="Center" Visibility="{Binding LoadingGridVisibility}"> 
           <Grid.RowDefinitions> 
            <RowDefinition/> 
           </Grid.RowDefinitions> 
           <Grid.ColumnDefinitions> 
            <ColumnDefinition/> 
            <ColumnDefinition/> 
           </Grid.ColumnDefinitions> 
           <ProgressRing x:Name="CustomProgressRing" Height="40" Width="40" IsActive="true" Grid.Column="0" Margin="20" Foreground="White"/> 
           <TextBlock Text="Loading Data" x:Name="CustomTextBlock" Height="auto" Width="auto" FontSize="25" Grid.Column="1" Margin="20"/> 
          </Grid> 
         </Grid> 
        </ScrollViewer> 
       </DataTemplate> 
      </FlipView.ItemTemplate> 

和資源:

<UserControl.Resources> 
    <DataTemplate x:Key="template1"> 
     <Grid x:Name="OptionItemGrid" Background="White" HorizontalAlignment="Stretch"> 
      <Grid.RowDefinitions> 
       <RowDefinition Height="Auto"/> 
       <RowDefinition Height="Auto"/> 
       <RowDefinition Height="Auto"/> 
       <RowDefinition Height="Auto"/> 
      </Grid.RowDefinitions> 
      <Grid.ColumnDefinitions> 
       <ColumnDefinition Width="*" /> 
       <ColumnDefinition Width="*" /> 
       <ColumnDefinition Width="*" /> 
       <ColumnDefinition Width="*" /> 
       <ColumnDefinition Width="*" /> 
      </Grid.ColumnDefinitions> 
      <!-- Content -->  
     </Grid> 
    </DataTemplate> 
    <DataTemplate x:Name="template2"> 
     <Grid x:Name="OptionItemGrid" Background="White" HorizontalAlignment="Stretch"> 
      <Grid.RowDefinitions> 
       <RowDefinition Height="Auto"/> 
       <RowDefinition Height="Auto"/> 
       <RowDefinition Height="Auto"/> 
       <RowDefinition Height="Auto"/> 
      </Grid.RowDefinitions> 
      <Grid.ColumnDefinitions> 
       <ColumnDefinition Width="*" /> 
       <ColumnDefinition Width="*" /> 
       <ColumnDefinition Width="*" /> 
      </Grid.ColumnDefinitions> 
      <!-- Content --> 
     </Grid> 
    </DataTemplate> 

    <local:OptionDataItemTemplateSelector x:Key="optionItemTemplateSelector" 
     Template1="{StaticResource template1}" 
     Template2="{StaticResource template2}"/> 
</UserControl.Resources> 

和模板選擇器類:

public class OptionDataItemTemplateSelector : DataTemplateSelector 
{ 

    public DataTemplate Template1 { get; set; } 
    public DataTemplate Template2 { get; set; } 

    protected override Windows.UI.Xaml.DataTemplate SelectTemplateCore(object item, Windows.UI.Xaml.DependencyObject container) 
    { 
     if(someCondition == 1) 
      return Template1; 
     else 
      return Template2;   
    } 
} 

回答

1

ItemTemplateSelector不能被觸發,除非ItemsSourceItem's實例中的ItemsSource未被更改。所以你想用ItemTemplateSelector實現的是扭曲的。 這樣做將是對你的ViewModel/CodeBehind一個屬性的簡單的方式說

bool IsClicked 
{ 
    get{return _isClicked;} 
    set 
    { 
    _isClicked = value 
    RaisePropertyChanged("IsClicked"); 
    } 
} 

和按鈕的CommandHandlerClick事件處理程序切換此屬性。

現在,您可以爲您的項目只是一個模板,像下面並改用ContentTemplate根據上面的屬性:

<DataTemplate x:Key="myTemplate"> 
    <ContentControl Content="{Binding}"> 
     <ContentControl.Style> 
      <Style TargetType="ContentControl"> 
      <Setter Property="ContentTemplate" Value="{StaticResource template1}"/> 
       <Style.Triggers> 
        <DataTrigger Binding="{Binding DataContext.IsClicked, RelativeSource={RelativeSource AncestorType={x:Type Window}}}" Value="false"> 
         <Setter Property="ContentTemplate" Value="{StaticResource template2}"/> 
        </DataTrigger 
       </Style.Triggers> 
      </Style> 
     </ContentControl.Style> 
    </ContentControl> 
    </DataTemplate> 
+0

我想要實現的是當我按下一個按鈕時ItemControl的內容被改變。我爲這2個DataTemplates定義了,我使用TemplateSelector在這兩個模板之間切換。我不知道這是否是正確的方式來做到這一點... –

+0

多數民衆贊成多數民衆贊成我所解釋的答案..模板選擇器不能以這種方式觸發..你將不得不重置您的控件的ItemsSource按鈕點擊爲了激發模板選擇器..或者你可以使用像我的答案中解釋的屬性和使用觸發器 – Nitin

+0

@nit我不能完全同意你說的關於調用模板選擇器只有當ItemsSource正確更改。我希望我不明白你錯了。模板選擇器適用於項目級別,而不是完整的ListBox級別。無論何時您添加項目或替換項目,模板選擇器都將針對該特定項目被調用。否則,如果模板選擇器只會偵聽ItemsSource屬性發生更改,它將永遠不會應用於新添加的項目,因爲添加項目時ItemSource屬性未更改。 –

0

如何貫穿您的項目並將someCondition設置爲1 ?

protected override Windows.UI.Xaml.DataTemplate SelectTemplateCore(object item, DependencyObject container) 
{ 
    if(ITEM.someCondition == 1) 
     return Template1; 
    else 
     return Template2;   
} 

在SelectTemplate方法裏面,你有所有你需要的信息。該項目來自數據源和數據源項目當前可視化的容器。 使用這些信息來決定哪個模板。

更改條件並返回其他模板。

+0

條件是硬編碼的一個。它加載正常,但如果我想在初始加載後更改模板?我想通過點擊某個按鈕來運行SelectTemplate方法,以便返回Template2(當然,我已經在btn點擊時將someCondition設置爲2)。...... –

+0

沒有一點黑客攻擊,這是不可能的。 –