在'模板化子元素'中访问父属性的正确方法是什么

时间:2013-12-28 15:30:43

标签: wpf silverlight mvvm

我创建了模板,模板元素遍历不是逻辑层次结构,而是遍历物理层次结构,例如直接窗口,直接视图。 这是为什么?在'模板化子元素'中访问父属性的正确方法是什么?

- 查看型号代码

public MainViewModel()
{
    if (IsInDesignMode)
    {
        Cars = new List<string>() { "Audi", "BMW", "Ferrari", "Ford" };
        Models = new List<string>() { "Model 1", "Model 2" };
    }
    else
    {
        Cars = new List<string>() { "Audi", "BMW", "Ferrari", "Ford" };
        Models = new List<string>() { "Model 1", "Model 2" };
    }
}

public List<string> Models { get; private set; }

public List<string> Cars { get; private set; }

项目模板选择器

public class ComboBoxTemplateSelector : DataTemplateSelector
{
    public override DataTemplate
        SelectTemplate(object item, DependencyObject container)
    {
        var element = container as FrameworkElement;

        var dataTemplate = element.FindResource(((item is string) && item.Equals("Ferrari")) ?
                                                       "DataTemplateTopLevelCombobox2" : "DataTemplateTopLevelCombobox1") as DataTemplate;

        return dataTemplate;
    }
}

- 主要应用程序xaml代码

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:proj="clr-namespace:WpfApplication1"
        Title="MainWindow" Height="350" Width="525" DataContext="{Binding Main, Mode=OneWay, Source={StaticResource Locator}}">
    <Window.Resources>
        <ItemsPanelTemplate x:Key="ItemsPanelTemplateHorizontal">
            <StackPanel IsItemsHost="True" Orientation="Horizontal"/>
        </ItemsPanelTemplate>
        <proj:QualityComboBoxTemplateSelector x:Key="QualityComboBoxTemplateSelector"/>
    </Window.Resources>

    <Grid>
        <ComboBox HorizontalAlignment="Left" VerticalAlignment="Top" Width="120" Margin="87.2,44.8,0,0" 
                  ItemsSource="{Binding Cars}" 
                  ItemsPanel="{DynamicResource ItemsPanelTemplateHorizontal}"
                  ItemTemplateSelector="{StaticResource ComboBoxTemplateSelector}"
                  x:Name="CarsComboBox"/>
    </Grid>
</Window>

资源字典

<DataTemplate x:Key="DataTemplateTopLevelCombobox1">
    <Border BorderBrush="Black" BorderThickness="1" >
        <TextBlock HorizontalAlignment="Left" TextWrapping="Wrap" Text="{Binding}" VerticalAlignment="Top"/>
    </Border>
</DataTemplate>

<DataTemplate x:Key="DataTemplateTopLevelCombobox2">
    <Border Width="100" >
        <ComboBox Text="Custom" Height="21.96"
        ItemsSource="{Binding DataContext.Models??"/>
    </Border>       
</DataTemplate>

1 个答案:

答案 0 :(得分:1)

我认为实现FindResource的方式是正确的,因为FindeResource在树中遍历并搜索具有指定键的资源。 FindResource

  

但是如果您已经知道您的ResourceDictionary已合并到应用程序资源,那么您可以直接访问它,如

App.Current.Resources["DataTemplateTopLevelCombobox2"]

如果您的ResourceDictionary合并到Window Resources但FindResource不合并,这将失败。