ContentControl与DataTemplateSelector - 需要帮助

6

我有一个非常烦人的问题... 或许有人可以(拜托啦!)帮帮我。 我正在使用一个模型,其中包含类型枚举和一个属性,该属性应为枚举中选择的每个类型保存UI模型:让我们将它们定义为:

class ViewModel
   {
     Types selectedType{get;set;}
     UiModelBase editedModel{get;set;}
   }

我希望有一个内容控件,使用DataTemplateSelector来在每次更改所选类型时更改视图。
    <ListBox x:Name="RuleTypeList" ItemsSource="{Binding Source={StaticResource Types}}" SelectedItem="{Binding Path=selectedType}"/>     
    <!--Content control-->
    <ContentControl ContentTemplateSelector="{StaticResource ruleEditTemplateSelector}" 
             Content="{Binding SelectedItem, ElementName=RuleTypeList}"/>

问题:我创建的DataTemplates将由ruleEditTemplateSelector返回。DataContext是Type(同意这一点),但我需要访问editedModel以创建我的DataTemplate...我不知道如何处理它。
谢谢!
2个回答

14

解决方案并不是很困难...

 DataContext="{Binding RelativeSource={RelativeSource AncestorType=ContentControl},Path=DataContext}"

这样,模板的上下文与其父级内容相同,我可以访问它的成员。我认为我尝试做到了,但我没有编写正确的代码... 感谢Cstein的参与!


谢谢!我已经寻找这个解决方案很长时间了。 - theateist

2
如果我理解正确,您想在模板选择器中创建数据模板,而数据模板基于editedModel属性。我会这样解决这个问题:
Windows.xaml:
<Window.Resources>
    <local:Selector x:Key="sel"/>

    <DataTemplate x:Key="templateA">
        <TextBlock Text="{Binding editedModel.PropertyName}"/>
    </DataTemplate>

    <DataTemplate x:Key="templateB">
        <TextBlock Text="{Binding editedModel.PropertyName}"/>
    </DataTemplate>

    <DataTemplate x:Key="templateC">
        <TextBlock Text="{Binding editedModel.PropertyName}"/>
    </DataTemplate>

</Window.Resources>

内容控件和列表框保持不变。

DataTemplateSelector:

public class Selector : DataTemplateSelector
{
    public override DataTemplate SelectTemplate(object item, DependencyObject container)
    {
        if (item is ClassA)
            return (container as FrameworkElement).FindResource("TemplateA") as DataTemplate;
        else if (item is ClassB)
            return (container as FrameworkElement).FindResource("TemplateB") as DataTemplate;
        else if (item is ClassC)
            return (container as FrameworkElement).FindResource("TemplateC") as DataTemplate;
        return null;
    }
}

这将根据项目类型返回现有的数据模板。我希望我理解得对,并且它能帮助到您。

不,这不是我的问题。我知道整个工作流程。问题出在模板A、B、C里面,因为找不到editedModel.PropertyName。(数据上下文是selectedType…) - Victor
如果你的 Window.xaml 的 DataContext 是你的 ViewModel,并且你将你的 DataTemplate 放在 Window.Resources 标签中,那么你可以从你的 DataTemplate 访问 editedModel.PropertyName。 - csteinmueller
是的,我在Windows.Resources中有DataTemplate,但不幸的是它说找不到任何:selectedType中的editedModel.PropertyName...这是真的... - Victor
只要你不声明它,它就找不到具有该名称的属性。或者我误解了你的意思? - csteinmueller
我担心我可能不理解你在说什么... editedModel.PropertyName的实例已经存在于代码后台...为什么我还要再声明一次...我想修改已经存在的实例。我理解错了吗? - Victor

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接