0

我在基础程序集中有一个控件,其中包含我想根据当前 DataContext 设置的内容。

为此,我尝试在调用程序集中使用资源和子类 DataTemplateSelector,如下所示。我最初的希望是调用子类 DataTemplateSelector,但事实并非如此。然后我尝试在调用程序集的资源字典中添加一个条目,使用相同的键但子类选择器,但这也没有完成。

有没有办法修复我必须使它工作的代码?有没有更好的策略来从调用程序集设置我的内容?

干杯,
贝里尔

用户控制(基本组件)

<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>
4

1 回答 1

0

我放弃了使 DataTemplateSelector 工作并最终执行以下操作:

  1. 创建一个 FilterContentConverter
  2. 将 FilterContentKey(字符串)添加到我的视图模型

转换器只需使用 FilterContentKey 并进行资源查找以获取具有该键的 DataTemplate。这最终可以很好地测试,甚至更好 - 它有效!

下面的解决方案代码,感谢Vladamir Dorokhov 和这个 SO 答案,帮助我获得 ContentControl 绑定权。

HTH,
绿柱石

过滤控制

在此处输入图像描述

<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(); }
}
于 2011-09-21T15:49:04.043 回答