【问题标题】:Binding a DataGrid's CellTemplate content to an Element or a DependencyProperty defined on the templated CustomControl将 DataGrid 的 CellTemplate 内容绑定到模板化 CustomControl 上定义的元素或 DependencyProperty
【发布时间】:2012-02-23 14:54:12
【问题描述】:

我在自定义控件中使用 WPF 的常规 DataGrid。 DataGrid 的单元格模板内容之一应绑定到 Textblock 的 Text 或自定义控件上的 DependencyProperty。 (如果我可以将它绑定到它们中的任何一个,那对我来说已经足够了)

我尝试使用 ElementName 进行以下绑定,但没有成功。我不断得到一个 DependencyProperty.UnsetValue -

<DataGridTemplateColumn Header="Test">
     <DataGridTemplateColumn.CellTemplate>
         <DataTemplate>
             <ContentPresenter>
                <ContentPresenter.Content>
                    <MultiBinding Converter="{StaticResource TextToSpecialTextblockConverter}">
                       <Binding Path="SomeTextOnTheViewModel"/>
                       <Binding ElementName="SearchBox" Path="Text" Mode="OneWay"/>
                    </MultiBinding>
                </ContentPresenter.Content>
             </ContentPresenter>
         </DataTemplate>
     </DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>

绑定到 DependencyProperty 也不起作用。

<DataGridTemplateColumn Header="Test">
     <DataGridTemplateColumn.CellTemplate>
         <DataTemplate>
             <ContentPresenter>
                <ContentPresenter.Content>
                    <MultiBinding Converter="{StaticResource TextToSpecialTextblockConverter}">
                       <Binding Path="SomeTextOnTheViewModel"/>
                       <Binding RelativeSource="{RelativeSource Mode=TemplatedParent}" Path="SomeDP" />
                    </MultiBinding>
                </ContentPresenter.Content>
             </ContentPresenter>
         </DataTemplate>
     </DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>

希望有人能帮帮我!

谢谢!

【问题讨论】:

  • SearchBox 是否在 DataGrid 之前定义?
  • 是的,它是在 DataGrid 之前定义的。

标签: wpf data-binding datagrid


【解决方案1】:

如果属性Property 定义在控件的DataContextDataGrid 上设置的视图模型上,则此示例有效:

资源:

    <DataTemplate x:Key="template">
        <StackPanel Orientation="Horizontal">
            <TextBlock Text="Test"/>
            <TextBlock Text="{Binding Path=DataContext.Property,RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}"/>
        </StackPanel>
    </DataTemplate>

数据网格

<DataGrid ItemsSource="{Binding Items}" ...>
    <DataGrid.Columns>
        <DataGridTemplateColumn CellTemplate="{StaticResource template}" />

DependencyProperty 更改通知可以更新视图模型。

例如:

    public static readonly DependencyProperty TestProperty =
        DependencyProperty.Register("Test", typeof (string), typeof (DataGridComboBoxColumn), new PropertyMetadata(default(string), PropertyChangedCallback));

    public string Test
    {
        get { return (string) GetValue(TestProperty); }
        set { SetValue(TestProperty, value); }
    }

    private static void PropertyChangedCallback(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)
    {
        ((MyControl) dependencyObject).OnTestChanged();
    }

    private void OnTestChanged()
    {
        ((MyViewModel) theGrid.DataContext).Property = Test;
    }

要使用模板绑定绑定到依赖属性Test,请使用此

<DataTemplate x:Key="template2">
    <StackPanel Orientation="Horizontal">
        <TextBlock Text="Test: "/>
        <TextBlock Text="{Binding Path=Test, RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type local:CustomControl1}}}"/>
    </StackPanel>
</DataTemplate>

<Style TargetType="{x:Type local:CustomControl1}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type local:CustomControl1}">
                <Border Background="{TemplateBinding Background}"
                        BorderBrush="{TemplateBinding BorderBrush}"
                        BorderThickness="{TemplateBinding BorderThickness}">
                    <DataGrid ItemsSource="{TemplateBinding ItemsSource}" AutoGenerateColumns="True">
                        <DataGrid.Columns>
                            <DataGridTemplateColumn Header="Test" CellTemplate="{StaticResource template2}" />
                        </DataGrid.Columns>
                    </DataGrid>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

CustomControl1 在哪里

public class CustomControl1 : ItemsControl
{
    static CustomControl1()
    {
        DefaultStyleKeyProperty.OverrideMetadata(
            typeof (CustomControl1),
            new FrameworkPropertyMetadata(typeof (CustomControl1)));
    }

    public static readonly DependencyProperty TestProperty =
        DependencyProperty.Register("Test", typeof (string), typeof (CustomControl1), new PropertyMetadata(default(string)));

    public string Test
    {
        get { return (string) GetValue(TestProperty); }
        set { SetValue(TestProperty, value); }
    }
}

【讨论】:

  • 嗨菲尔,谢谢你的回答!但在我的情况下,没有 ViewModel,只有一个带有 DependencyProperties 的 CustomControl .cs 文件。我知道我可以创建一个这样我就可以使用您的解决方案,但这似乎有点矫枉过正,我想知道对于这样一个简单的请求是否有更优雅的解决方案。
  • 今晚我将再次尝试绑定到依赖项属性。然而,一个更简单的解决方案是在绑定到网格的 ItemsSource 之前将多转换器中的逻辑应用于数据。使用一点 Linq 应该很容易。
  • 嗯,这是一个有趣的想法,尽管它看起来不是一个标准的解决方案,而是一个即兴创作,但也许它会做!我会尝试一下,但如果有一个优雅的解决方案,我会更喜欢它!谢谢!
  • 嘿 Phil,我一直在考虑您的解决方案,我一直想知道在 itemssource 上使用 Multi-Binding 是否会影响性能,因为每次 DependencyProperty 都会设置 itemssource会改变。这可能会发生很多,因为它实际上是一个受用户影响的文本字段。突然间,我不确定即使是这个解决方案也能成立。我只是不明白为什么他们搞砸了 DataGrid,所以它不适用于 ElementName。也许我会切换回 ListView。
  • 这取决于集合的大小。如果收藏在 1000 件之内,可能不会花很长时间,数百万件将是一个问题。您必须对其进行测试。
猜你喜欢
  • 1970-01-01
  • 2019-04-08
  • 1970-01-01
  • 2010-10-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-30
相关资源
最近更新 更多