【问题标题】:What’s right way to access parent property inside of ‘templated child element’在“模板化子元素”中访问父属性的正确方法是什么
【发布时间】:2013-12-28 15:30:43
【问题描述】:

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

--查看模型代码

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>

【问题讨论】:

  • 实际上我的问题是关于数据绑定ItemsSource="{Binding DataContext.Models??"/&gt;,对于这个绑定,我尝试了不同的方法,比如ItemsSource="{Binding Path=DataContext.Models, RelativeSource={RelativeSource TemplatedParent}}"ItemsSource="{Binding Path=DataContext.RecordingResolutions, RelativeSource={RelativeSource {RelativeSource FindAncestor, AncestorType={x:Type ComboBox}}}}"。但没有任何效果。如果您能指导我为此设置数据上下文,将会很有帮助。
  • 我的问题在覆盖 Border 的数据上下文后得到解决,如下&lt;DataTemplate x:Key="DataTemplateTopLevelCombobox2"&gt; &lt;Border Width="100" DataContext="{Binding DataContext, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ComboBox}}}"&gt; &lt;ComboBox Text="Custom" Height="21.96" ItemsSource="{Binding Models}"/&gt; &lt;/Border&gt; &lt;/DataTemplate&gt;

标签: wpf silverlight mvvm


【解决方案1】:

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

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

App.Current.Resources["DataTemplateTopLevelCombobox2"]

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

【讨论】:

    猜你喜欢
    • 2012-06-14
    • 2017-02-24
    • 1970-01-01
    • 2014-06-14
    • 1970-01-01
    • 2018-06-09
    • 2017-06-01
    • 2014-07-31
    • 1970-01-01
    相关资源
    最近更新 更多