2011-09-18 66 views
0

我在基本程序集中有一個控件,其中包含我想基於當前DataContext設置的內容。使用來自不同程序集的資源和DataTemplateSelector

爲此,我試圖在調用程序集中使用資源和子類DataTemplateSelector,如下所示。我最初的希望是調用子類DataTemplateSelector,但事實並非如此。然後我嘗試在調用程序集的資源字典中使用相同的鍵添加一個條目,但使用了子類選擇器,但是這也不能完成。

有沒有辦法解決我必須使這項工作的代碼?有沒有更好的策略來設置來自調用程序集的內容?

乾杯,
Berryl

用戶控制(底座組件)

<UserControl 
    ... 

    <Grid> 
     <Border Style="{StaticResource FilterPanelBorderStyle}"> 
      <StackPanel Orientation="Horizontal" x:Name="myFilterPanel" > 

     *****  <ContentControl x:Name="ctrlFilters" ContentTemplateSelector="{StaticResource filterControlsTemplateSelector}" /> **** 

       <Button x:Name="btnClearFilter" Style="{StaticResource FilterPanelClearButtonStyle}" /> 
       <Label x:Name="lblStatus" Style="{StaticResource FilterPanelLabelStyle}" Content="{Binding Status}" /> 

      </StackPanel> 
     </Border> 

    </Grid> 
</UserControl> 

資源和DataTemplateSelector(底座組件)

<views:FilterControlsTemplateSelector x:Key="filterControlsTemplateSelector"/> 

<DataTemplate x:Key="defaultFilterContent"> 
    <TextBlock>Replace ME with real filters!</TextBlock> 
</DataTemplate> 

    public class FilterControlsTemplateSelector : DataTemplateSelector 
{ 
    public override DataTemplate SelectTemplate(object item, DependencyObject container) 
    { 
     var fe = container as FrameworkElement; 
     if (fe == null) return null; 

     return _GetDataTemplate(fe); 
    } 

    protected virtual DataTemplate _GetDataTemplate(FrameworkElement fe) { 
     var template = fe.FindResource("defaultFilterContent") as DataTemplate; 
     return template; 
    } 
} 

資源和選擇器(調用部件)

<ResourceDictionary.MergedDictionaries> 
    <ResourceDictionary Source="pack://application:,,,/Core.Presentation.Wpf;component/Themes/Generic.xaml" /> 
</ResourceDictionary.MergedDictionaries> 

<local:PimFilterControlsTemplateSelector x:Key="filterControlsTemplateSelector"/> 

<DataTemplate x:Key="pimFilterContent"> 
    <Grid> 
     <Border Style="{StaticResource FilterPanelBorderStyle}"> 
      <StackPanel Orientation="Horizontal" > 
       <cc:SearchTextBox 
         x:Name="stbLastNameFilter" Style="{StaticResource FilterPanelSearchTextBoxStyle}" 
         /> 
       <cc:SearchTextBox 
         x:Name="stbFirstNameFilter" Style="{StaticResource FilterPanelSearchTextBoxStyle}" 
         /> 
      </StackPanel> 
     </Border> 

    </Grid> 
</DataTemplate> 


public class PimFilterControlsTemplateSelector : FilterControlsTemplateSelector 
{ 

    protected override DataTemplate _GetDataTemplate(FrameworkElement fe) 
    { 
     var dc = fe.DataContext; 
     if (dc == null) return null; 

     DataTemplate result = null; 
     if (dc is PimMasterVm) 
     { 
      result = fe.FindResource("pimFilterContent") as DataTemplate; 
     } 
     else { 
      result = base._GetDataTemplate(fe); 
     } 
     return result; 
    } 

} 

應用詞典的設置(調用組件)

<Application.Resources> 
    <ResourceDictionary> 
     <ResourceDictionary.MergedDictionaries> 
      <ResourceDictionary Source="pack://application:,,,/Parties.Presentation.Wpf;component/PimCommonResources.xaml" />     
     </ResourceDictionary.MergedDictionaries> 
    </ResourceDictionary> 

</Application.Resources> 

回答

0

我放棄了使DataTemplateSelector工作和清盤執行以下操作:

  1. 創建FilterContentConverter
  2. 加入FilterContentKey(串)我的觀點模型

該轉換器只需要FilterContentKey和做es資源查找以獲取具有該密鑰的DataTemplate。這樣可以很好地測試,甚至更好 - 它的工作原理!

以下解決方案代碼,感謝Vladamir Dorokhov and this SO answer幫助我獲得ContentControl綁定的權利。

HTH,
Berryl

濾波控制

enter image description here

<Grid> 
    <Border Style="{StaticResource FilterPanelBorderStyle}"> 
     <StackPanel Orientation="Horizontal" x:Name="myFilterPanel" > 
      <ContentControl x:Name="ctrlFilters" 
          ContentTemplate="{Binding Path=FilterContentKey, Converter={StaticResource filterTemplateContentConv}}" /> 
      <Button x:Name="btnClearFilter" Style="{StaticResource FilterPanelClearButtonStyle}" /> 
      <Label x:Name="lblStatus" Style="{StaticResource FilterPanelLabelStyle}" Content="{Binding Status}" /> 

     </StackPanel> 
    </Border> 

</Grid> 

數據模板(資源)

<DataTemplate x:Key="pimFilterContent"> 
    <StackPanel Orientation="Horizontal" > 
     <cc:SearchTextBox x:Name="stbLastNameFilter" 
      Style="{StaticResource FilterPanelSearchTextBoxStyle}" 
      Text="{Binding Path=LastNameFilter, UpdateSourceTrigger=PropertyChanged}" 
         /> 
     <cc:SearchTextBox x:Name="stbFirstNameFilter" 
      Style="{StaticResource FilterPanelSearchTextBoxStyle}" 
      Text="{Binding Path=FirstNameFilter, UpdateSourceTrigger=PropertyChanged}" 
         /> 
    </StackPanel> 
</DataTemplate> 

轉換器

/// <summary> 
/// Thin wrapper around a resource lookup designed to result in a <see cref="DataTemplate"/> 
/// representing filering controls. 
/// </summary> 
[ValueConversion(typeof(object), typeof(DataTemplate))] 
public class FilterTemplateContentConverter : IValueConverter 
{ 
    public const string DEFAULT_CONTENT = "undefinedFilterContent"; 
    protected readonly ResourceLocator _resourceLocator; 

    /// <summary> 
    /// Initializes a new instance of the <see cref="FilterTemplateContentConverter"/> class. 
    /// Unit tests can use this to pass in an app for the <see cref="ResourceLocator"/>. 
    /// </summary> 
    /// <param name="app">The app.</param> 
    public FilterTemplateContentConverter(Application app) { _resourceLocator = new ResourceLocator(app); } 

    /// <summary> 
    /// Initializes a new instance of the <see cref="FilterTemplateContentConverter"/> class. 
    /// The 'real' application uses this. 
    /// </summary> 
    public FilterTemplateContentConverter() 
    { 
     _resourceLocator = new ResourceLocator(); 
    } 

    public virtual object Convert(object value, Type targetType, object parameter, CultureInfo culture) { 
     var key = value as string; 
     return _resourceLocator.GetResource(key ?? DEFAULT_CONTENT); 
    } 

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