使用来自不同程序集的资源和 DataTemplateSelector
我在基础程序集中有一个控件,其中包含我想根据当前 DataContext 设置的内容。
为此,我尝试在调用程序集中使用资源和子类 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>
I have a control in a base assembly with Content that I would like to set based on the current DataContext.
To do so, I am trying to use a resource and subclassed DataTemplateSelector in the calling assembly as shown below. My initial hope was that the sub classed DataTemplateSelector would be called, but it isn't. Then I tried adding an entry in the Resource Dictionary of the calling assembly with the same key but the sub classed selector, but that doesn't get it done either.
Is there a way to fix the code I have to make this work? Is there a better strategy to set my content from the calling assembly?
Cheers,
Berryl
User Control (base assembly)
<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>
Resources and DataTemplateSelector (base assembly)
<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;
}
}
Resources and Selector (calling Assembly)
<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 Dictionary setup (calling assembly)
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/Parties.Presentation.Wpf;component/PimCommonResources.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我放弃了让 DataTemplateSelector 工作并最终执行以下操作:
该转换器仅获取 FilterContentKey 并执行资源查找以获取具有该键的 DataTemplate。这最终可以很好地进行测试,甚至更好 - 它有效!
下面的解决方案代码,感谢 Vladamir Dorokhov 和这个 SO 答案帮助我正确绑定 ContentControl。
HTH,
Berryl
过滤控件
数据模板(资源)
转换器
I gave up on making the DataTemplateSelector work and wound up doing the following:
The converter just takes the FilterContentKey and does a resource lookup to get the DataTemplate with that key. This winds up being nicely testable, and even better - it works!
Solution code below, with thanks to Vladamir Dorokhov and this SO answer for helping me get the ContentControl binding right.
HTH,
Berryl
Filtering Control
Data Template (resource)
Converter