繁体   English   中英

从ControlTemplate绑定到ViewModel

[英]Bind from ControlTemplate to ViewModel

我将问题简化为一个最小的示例:我的DataGrid由ControlTemplate定义,并且在那个ControlTemplate中,我无法绑定到ViewModel中的任何内容。

这是简化的ViewModel:

public class ViewModel : PropertyChangedBase
{
    private string text1;

    public ViewModel()
    {
        this.text1 = "tx1!";
    }

    public string Text1
    {
        get { return text1; }
        set
        {
            if (value == text1) return;
            text1 = value;
            NotifyOfPropertyChange(() => Text1);
        }
    }
}

我尝试使用几种方法绑定到Text1 我在Google上找到的大多数内容都建议使用FindAncestor但它也不起作用:

<Window x:Class="DataGridTemplateBinding.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:DataGridTemplateBinding"
        Title="MainWindow" Height="350" Width="525"
        x:Name="LayoutRoot"
        >
    <Window.Resources>
        <ControlTemplate x:Key="TableTemplate">
            <DataGrid>
                <DataGrid.Columns>
                    <DataGridTextColumn Header="Column 1" />
                    <!-- by ElementName -->
                    <DataGridTextColumn Header="{Binding DataContext.Text1, ElementName=LayoutRoot}" />
                    <DataGridTextColumn Header="{Binding Text1, ElementName=LayoutRoot}" />

                    <!-- by Ancestor type (Window) -->
                    <DataGridTextColumn Header="{Binding DataContext.Text1, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}}" />
                    <DataGridTextColumn Header="{Binding Text1, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}}" />

                    <!-- by templated parent -->
                    <DataGridTextColumn Header="{Binding DataContext.Text1, RelativeSource={RelativeSource TemplatedParent}}" />
                    <DataGridTextColumn Header="{Binding Text1, RelativeSource={RelativeSource TemplatedParent}}" />

                    <!-- by self?? -->
                    <DataGridTextColumn Header="{Binding DataContext.Text1, RelativeSource={RelativeSource Self}}" />
                    <DataGridTextColumn Header="{Binding Text1, RelativeSource={RelativeSource Self}}" />

                    <DataGridTextColumn Header="{Binding Content.DataContext.Text1, RelativeSource={RelativeSource TemplatedParent}}" />
                    <DataGridTextColumn Header="{Binding Content.Text1, RelativeSource={RelativeSource TemplatedParent}}" />

                    <DataGridTextColumn Header="{Binding DataContext.Text1}" />
                    <DataGridTextColumn Header="{Binding Text1}" />

                    <DataGridTextColumn Header="Column End" />
                </DataGrid.Columns>
            </DataGrid>
        </ControlTemplate>
    </Window.Resources>
    <Window.DataContext>
        <local:ViewModel />
    </Window.DataContext>
    <Grid>
        <DataGrid Template="{StaticResource TableTemplate}" />
    </Grid>
</Window>

模板中的列如何绑定到ViewModel中的任何内容? 我无法想象这是不可能的。


为了完整起见,这些是记录到输出中的错误。 他们为了与XAML的顺序相对应。

System.Windows.Data错误:40:BindingExpression路径错误:在“对象”“ DataGridTextColumn”(HashCode = 28365320)”上找不到“ DataContext”属性。 BindingExpression:路径= DataContext.Text1; DataItem ='DataGridTextColumn'(HashCode = 28365320); 目标元素是'DataGridTextColumn'(HashCode = 28365320); 目标属性为“标题”(类型为“对象”)

System.Windows.Data错误:40:BindingExpression路径错误:在'object''DataGridTextColumn'(HashCode = 54811268)'上找不到'Text1'属性。 BindingExpression:路径=文本1; DataItem ='DataGridTextColumn'(HashCode = 54811268); 目标元素是“ DataGridTextColumn”(HashCode = 54811268); 目标属性为“标题”(类型为“对象”)

System.Windows.Data错误:2:找不到目标元素的管理FrameworkElement或FrameworkContentElement。 BindingExpression:路径= DataContext.Text1; 的DataItem = NULL; 目标元素是“ DataGridTextColumn”(HashCode = 55195297); 目标属性为“标题”(类型为“对象”)

System.Windows.Data错误:2:找不到目标元素的管理FrameworkElement或FrameworkContentElement。 BindingExpression:路径=文本1; 的DataItem = NULL; 目标元素是“ DataGridTextColumn”(HashCode = 38845522); 目标属性为“标题”(类型为“对象”)

System.Windows.Data错误:4:找不到参考'RelativeSource FindAncestor,AncestorType ='System.Windows.Window',AncestorLevel ='1''的绑定源。 BindingExpression:路径= DataContext.Text1; 的DataItem = NULL; 目标元素是'DataGridTextColumn'(HashCode = 2399386); 目标属性为“标题”(类型为“对象”)

System.Windows.Data错误:4:找不到参考'RelativeSource FindAncestor,AncestorType ='System.Windows.Window',AncestorLevel ='1''的绑定源。 BindingExpression:路径=文本1; 的DataItem = NULL; 目标元素是“ DataGridTextColumn”(HashCode = 31265986); 目标属性为“标题”(类型为“对象”)

System.Windows.Data错误:2:找不到目标元素的管理FrameworkElement或FrameworkContentElement。 BindingExpression:路径= DataContext.Text1; 的DataItem = NULL; 目标元素是“ DataGridTextColumn”(HashCode = 6837024); 目标属性为“标题”(类型为“对象”)

System.Windows.Data错误:2:找不到目标元素的管理FrameworkElement或FrameworkContentElement。 BindingExpression:路径=文本1; 的DataItem = NULL; 目标元素是'DataGridTextColumn'(HashCode = 17422861); 目标属性为“标题”(类型为“对象”)

System.Windows.Data错误:2:找不到目标元素的管理FrameworkElement或FrameworkContentElement。 BindingExpression:路径= Content.DataContext.Text1; 的DataItem = NULL; 目标元素是“ DataGridTextColumn”(HashCode = 32669489); 目标属性为“标题”(类型为“对象”)

System.Windows.Data错误:2:找不到目标元素的管理FrameworkElement或FrameworkContentElement。 BindingExpression:路径= Content.Text1; 的DataItem = NULL; 目标元素是“ DataGridTextColumn”(HashCode = 22361045); 目标属性为“标题”(类型为“对象”)

System.Windows.Data错误:2:找不到目标元素的管理FrameworkElement或FrameworkContentElement。 BindingExpression:路径= DataContext.Text1; 的DataItem = NULL; 目标元素是“ DataGridTextColumn”(HashCode = 7953856); 目标属性为“标题”(类型为“对象”)

System.Windows.Data错误:2:找不到目标元素的管理FrameworkElement或FrameworkContentElement。 BindingExpression:路径=文本1; 的DataItem = NULL; 目标元素是“ DataGridTextColumn”(HashCode = 65911433); 目标属性为“标题”(类型为“对象”)

设置DataGridTextColumnHeaderTemplate如下所示

<DataGridTextColumn  >
    <DataGridTextColumn.HeaderTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=DataContext.Text1}"></TextBlock>
        </DataTemplate>
    </DataGridTextColumn.HeaderTemplate>
</DataGridTextColumn>

通过所有提示,我发现DataGridTextColumn既不是可视树的一部分,也不是逻辑树的一部分。 这应该是ElementNameRelativeSource不起作用的原因。 关于DataGridTextColumn此答案说明了这一点,并提供了使用Sourcex:Reference的可能解决方案: DataGridTextColumn可见性绑定

@Anand Murali的答案有效,但不能应用于Visibility -这不是问题的一部分,因为我将其最小化了。 因此,我接受这一观点,并将在这一观点中提供更多信息。

使用x:Reference for Visibility ,结果可能像这样:

<DataGridTextColumn Binding="{Binding Data.OrderNumber}" Header="Order Number" Visibility="{Binding DataContext.ShowColumnOrderNumber, Source={x:Reference LayoutRoot}, Converter={StaticResource BooleanToVisibilityConverter}}" />

但是:在我的示例中,我使用ControlTemplate并使x:Reference起作用,该模板必须在同一文件的.Resources XAML部分中,并且不能在外部ResourceDictionary 在后一种情况下,该引用将不起作用,因为无法解析。 (如果有人知道解决方案,那将是受欢迎的)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM