【问题标题】:Using FindAncestor from within an Itemscontrol datatemplate to find a textblock outside of the datatemplate在 Itemscontrol 数据模板中使用 FindAncestor 在数据模板之外查找文本块
【发布时间】:2012-11-09 21:28:52
【问题描述】:

我有一个绑定到对象的 ItemsControl,在 ItemsControl 的数据模板中我有两个文本块,我想将第一个文本块的文本属性绑定到位于此 ItemsControl 之外的另一个文本块。

我已尝试在父数据上下文中查找对象,也只是尝试使用 Path=Text 查找 TextBlock

一个例子如下:

 <TextBlock Name="Name" Text="{Binding Name}"                                                            
     Grid.Column="0"   
     FontSize="{DynamicResource SmallSize}"
     TextWrapping="Wrap"
     TextAlignment="Right"
     Padding="4,0,0,0"
     Grid.ColumnSpan="2" Background="Aqua"/>

     <ItemsControl ItemsSource="{Binding TheValue}"                                                  
         Padding="4,0,0,0" 
         Grid.Column="2"  
         HorizontalAlignment="Right">

         <ItemsControl.ItemTemplate>
             <DataTemplate>
                 <WrapPanel>
                     <TextBlock Text = "{
                           Binding RelativeSource = 
                               {RelativeSource FindAncestor, 
                                AncestorType={x:Type Window}}, Path=Name}"                                                                                                            
                           Grid.Column="0"
                           FontSize="{DynamicResource SmallSize}"
                           TextWrapping="Wrap" ........................

【问题讨论】:

    标签: wpf relativesource findancestor


    【解决方案1】:
    {Binding RelativeSource = {RelativeSource FindAncestor,
                               AncestorType={x:Type Window}}, Path=Name}
    

    在这里,您对 WPF 说使用 Type Window 找到此控件的第一个父级,例如它是“父窗口”。在此绑定发生在“ParentWindow”Name 属性之后。

    如果要启用绑定到在相同 XAML 中定义的控件,可以使用 Binding.ElementName 属性显式设置源。 这是您的代码示例:

    <TextBlock Text = "{Binding ElementName=Name, Path=Text}"/>
    

    顺便说一句,使用控件名称作为“名称”不是很好。如果您在其后面使用此控件表单代码,则它看起来像 Name.Text = "some text",这可能会导致难以理解正在发生的事情。

    更新: 绑定到不同数据模板中的DataContext属性的示例

    class MainViewModel
    {
        public Class1 C1 { get; set; }
        public Class2 C2 { get; set; }
    
        public MainViewModel()
        {
            C1 = new Class1 { S1 = "This is C1 data context" };
            C2 = new Class2 { S2 = "This is C2 data context" };
        }
    }
    

    在 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:local="clr-namespace:WpfApplication1"        
            Title="MainWindow" Height="350" Width="525">
        <Window.Resources>
            <DataTemplate DataType="{x:Type local:MainViewModel}">
                <StackPanel>
                    <ContentControl Name="cc1" Content="{Binding C1}"/>
                    <ContentControl Name="cc2" Content="{Binding C2}"/>
                </StackPanel>
            </DataTemplate>
            <DataTemplate DataType="{x:Type local:Class1}">
                <TextBlock Text="{Binding S1}"/>
            </DataTemplate>
            <DataTemplate DataType="{x:Type local:Class2}">
                <TextBlock Text="{Binding ElementName=cc1, Path=DataContext.C1.S1}"/>
            </DataTemplate>
        </Window.Resources>
    
        <Grid>
            <ContentControl Content="{Binding}"/>
        </Grid>
    </Window>
    

    但是,我认为这样的方法不是一个好方法。特别是,因为这可能是这个 DataTemplate 的许多项目。也许您需要将此委托给您的 ViewModel。

    【讨论】:

    • 感谢 Eugene,名称“name”仅用于发布目的,真实对象更具描述性:) 如果我想绑定到同一个 xmal 中另一个数据上下文中的对象,我会怎么做但是在不同的数据模板中?这是你看到的真正问题:) 问候
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-03-29
    • 1970-01-01
    • 1970-01-01
    • 2018-09-27
    • 2020-04-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多