在DataTemplate.Triggers中设置DataTemplate.VisualTree

时间:2012-07-16 19:35:40

标签: c# wpf mvvm

大家好,我正在尝试更改dataGrid中列的模板,但我找不到在XAML中执行此操作的方法。我试图通过这种方式来做到这一点

<DataTemplate>
    <DataTemplate.Triggers>
        <Trigger Property="{Binding ElementName=isComboBox, Path=IsChecked}"
                 Value="True">
            <Setter Property="VisualTree">
                <Setter.Value>
                    <ComboBox ItemsSource="{Binding elementos}"/>                
                </Setter.Value>
            </Setter>
        </Trigger>
    </DataTemplate.Triggers>
</DataTemplate>

但是一个错误告诉我The property VisualTree cannot be set as a property element on template. Only Triggers and Storyboards are allowed as property elements是否有人知道根据另一个控件在DataGridCell中更改模板的不同方式?

1 个答案:

答案 0 :(得分:2)

您不会更改模板中的模板,这不是它的工作原理。

有很多方法可以做到这一点。取决于您的应用程序的配置方式。最常见的方法是

  1. ContentControl或ItemsControl绑定到属性/集合
  2. 该集合包含一个或多个不同类型的实例
  3. 您可以在应用程序的资源中定义DataTemplates,其中DataType与您的实例类型相匹配
  4. 例如,您的应用程序中有几个模型

    public sealed class Foo
    {
        public string Text {get;set;}
    }
    
    public sealed class Bar
    {
        public bool Checked {get;set;}
    }
    

    您的应用程序公开包含一个或多个这些实例的属性

    public partial class MainWindow : Window
    {
        //INotifyPropertyChanged/DependencyObject stuff left out!
        public object FooOrBar {get;set;} 
    
        //snip
    }
    

    在您的XAML中,您有一个扩展ItemsControlContentControl或类似的UIElement类型,可以绑定到该属性。

    <Window 
        x:Name="root"
        xmlns:t="clr-namespace:MyApplicationWhereFooAndBarLive"
        SkipAllThatXmlnsDefinitionNonsenseForSpaceSavingsInThisExample="true"/>  
        <!-- see Resources below --> 
        <ConentControl Content="{Binding FooOrBar, ElementName=root}" />
    </Window>
    

    最后,您在应用程序的资源中为每个类型定义DataTemplates

    <Window.Resources>
        <DataTemplate DataType="{x:Type t:Foo}">
            <TextBox Text="{Binding Text}" />
        </DataTemplate >
        <DataTemplate DataType="{x:Type t:Bar}">
            <CheckBox Checked="{Binding Checked}" />
        </DataTemplate >
    </Window.Resources>
    

    DataTemplate选择的过程如下:

    1. 某人设置(我们在这个例子中说)FooOrBar = new Foo();
    2. ContentControl的内容绑定更新(通过INPC或DependencyProperty)
    3. ContentControl查找其DataTemplateSelector,找不到任何配置并使用默认实现。
    4. 默认的DataTemplateSelector获取绑定到Content属性的对象的类型。
    5. DataTemplateSelector(本质上)为logical tree查找资源,该资源是DataTemplate,其密钥类型与步骤4中标识的实例类型相匹配。
    6. 找到DataTemplate,并将其传递给ConentControl
    7. ContentControl通过LoadContent()方法加载可视树。
    8. ContentControl将此可视化树的根的DataContext设置为Content属性中的值(在我们的示例中,是Foo的新实例)
    9. 此可视化树(IIRC)已添加为ConentControl的子级,现在可在UI中显示。
    10. 除了添加中间件之外,ItemsControl大致相同(即,ListBox使用ListBoxItem作为中介,LBI是ContentControl)。