2013-08-28 76 views
1

對於我的應用程序,我有一個ItemsControl,它具有用於第一項的獨特模板(簡稱爲Template2)和其餘項目的默認模板(Template1)。我曾與下面的XAML這樣做:強制更新WPF中的RelativeSource綁定

<DataTemplate x:Key="MyDataTemplate"> 
    <ContentPresenter x:Name="TemplateContentPresenter" 
         Content="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Content}" 
         ContentTemplate="{StaticResource Template1}"/> 
    <DataTemplate.Triggers> 
     <DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, 
    Converter= {StaticResource IsFirstItemInCollectionConverter}}" 
        Value="True"> 
      <Setter TargetName="TemplateContentPresenter" 
        Property="ContentTemplate" 
        Value="{StaticResource Template2}"/> 
     </DataTrigger> 
    </DataTemplate.Triggers> 
</DataTemplate> 

的IsFirstItemInCollectionConverter的代碼如下:

public class IsFirstItemInCollectionConverter : IValueConverter 
{ 
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 
    { 
     DependencyObject item = (DependencyObject)value; 
     ItemsControl ic = ItemsControl.ItemsControlFromItemContainer(item); 
     Console.WriteLine("converted"); 
     return (ic.ItemContainerGenerator.IndexFromContainer(item) == 0); 
    } 

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 
    { 
     throw new NotImplementedException(); 
    } 
} 

的問題是,我結合我做ItemsControl中的的ItemsSource的變化不更新。 (在顯示itemsControl的視圖中,我有可以添加和刪除項目的按鈕)。綁定更新並僅在切換視圖後顯示正確的模板,然後重新加載它。我怎樣才能糾正這種行爲?我假設我必須將UpdateSourceTrigger設置爲顯式並手動更新源,但我不知道如何在數據模板內部執行此操作。先謝謝您的幫助。

回答

2

您已觸發您的DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}當ListBoxItem的datacontext發生更改時,將觸發它。

我會在這裏建議使用DataTemplateSelector來進行物品控制,並設置ItemTemplateSelector屬性。在SelectTemplate方法,你可以爲新添加的項目返回模板依賴於任何邏輯:

TemplateSelector:

public class MyTemplateSelector : DataTemplateSelector 
{ 
    public DataTemplate FirstItemTemplate { get; set; } 
    public DataTemplate DefaultItemTemplate { get; set; } 

    public override DataTemplate SelectTemplate(object item, DependencyObject container) 
    { 
     //Logic to return first or default template comes here 
    } 
} 

在XAML:

<local:MyTemplateSelector x:Key="myTemplate"> 
     <local:MyTemplateSelector.FirstItemTemplate> 
      <!--First Template--> 
     </local:MyTemplateSelector.FirstItemTemplate> 

     <local:MyTemplateSelector.DefaultItemTemplate> 
      <!--Default Template--> 
     </local:MyTemplateSelector.DefaultItemTemplate> 
    </local:MyTemplateSelector> 

UPDATE

爲您的特定如果你沒有在你的itemsControl中使用替換,你可以像下面這樣解決這個問題。你可以使用AlternationCount給你ListBox並綁定到每個ListboxItem的ItemsControl.AlternationIndex。所以每當列表框交替指數的變化可以改變它的模板:

XAML:

<ListBox AlternationCount="{Binding Items.Count, RelativeSource={RelativeSource Self}}" x:Name="itemControl" ItemsSource="{Binding Items}"> 
     <ListBox.ItemContainerStyle> 
      <Style TargetType="{x:Type ListBoxItem}"> 
       <Setter Property="Template" Value="{StaticResource DefaultTemplate}" /> 
       <Style.Triggers> 
        <Trigger Property="ItemsControl.AlternationIndex" Value="0"> 
         <Setter Property="Template" Value="{StaticResource FirstTemplate}" /> 
        </Trigger> 
       </Style.Triggers> 
      </Style> 
     </ListBox.ItemContainerStyle> 
    </ListBox> 

這裏DefaultTemplate和FirstTemplate是CONTROLTEMPLATES。

我試過了,每當我刪除索引爲0的項目時,它都會爲我工作,它會給出下一個項目的第一個項目模板。

希望它適合你。

謝謝,

+0

你好,謝謝你的回覆。我使用了你描述的方法,但同樣的問題發生了;當我刪除I​​temControl綁定的ObservableCollection的索引0時,模板不會立即更新。在更新應用之前,我需要切換視圖。你還有其他建議嗎? –

+0

@ClementHoang爲你做了更新的答案嗎? – Nitin

0

好吧,我固定它,但在一個不雅的態度。每次刪除/添加項目時,我都會將綁定項目臨時設置爲null以強制DataTemplateSelector進行重新評估。

+0

請看我的回答更新是否對你有幫助。謝謝 – Nitin