如何在 WPF 中绑定用户控件作为 DataGridTemplateColumn 失败

2024-04-29

我想使用来自不同程序集的用户控件作为 DataGridTemplateColumn。 我已经看过很多例子和问题,比如this https://stackoverflow.com/questions/13956767/binding-to-custom-dependency-property-again, this https://stackoverflow.com/questions/5698865/simple-dependency-property-and-usercontrol-issues-in-c-sharp, this https://stackoverflow.com/questions/16694327/how-to-binding-a-itemscontrol-itemssource-with-a-property-of-the-window-in-wpf and this http://zamjad.wordpress.com/2009/12/30/using-user-control-in-data-grid/。我不明白为什么我的代码不起作用。 这里是:

主窗口.xaml

<Window x:Class="WpfTemplatesDemo3.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:extraUserControl="clr-namespace:Templates;assembly=Templates"
    xmlns:wpfTemplatesDemo3="clr-namespace:WpfTemplatesDemo3"
    Title="MainWindow" Height="350" Width="525">
<Grid>
    <DataGrid x:Name="TableDataGrid" DataContext="{Binding   UpdateSourceTrigger=PropertyChanged}" AutoGenerateColumns="False" >
        <DataGrid.Columns>
            <DataGridTextColumn Binding="{Binding Name}" Width="*"/>
            <DataGridTextColumn Binding="{Binding Age}" Width="*"/> 
            <DataGridTextColumn Binding="{Binding Description}" Width="2*"/>
            <DataGridTemplateColumn  Width="3*" >
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <extraUserControl:BirthDateControl BirthDayObj="{Binding BirthDay, ElementName=TableDataGrid}"   />
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>
        </DataGrid.Columns>
    </DataGrid>
</Grid>
</Window>

MainWindow.xaml.cs

namespace WpfTemplatesDemo3
{
  public partial class MainWindow : Window
  {
    public ObservableCollection<Person> Persons { get;set; }

    public MainWindow()
    {
      InitializeComponent();
      this.populatePersons();
      this.TableDataGrid.ItemsSource = this.Persons;
    }

    private void populatePersons()
    {
      this.Persons = new ObservableCollection<Person>();
      Persons.Add(new Person { Age = 10, Name = "John0", BirthDay = new BirthDate(1, 2, 3) });
      Persons.Add(new Person { Age = 11, Name = "John1", BirthDay = new BirthDate(2, 3, 4) });
      Persons.Add(new Person { Age = 12, Name = "John2", BirthDay = new BirthDate(3, 4, 5) });
      Persons.Add(new Person { Age = 13, Name = "John3", BirthDay = new BirthDate(4, 5, 6) });
      Persons.Add(new Person { Age = 14, Name = "John4", BirthDay = new BirthDate(5, 6, 7) });
      Persons.Add(new Person { Age = 15, Name = "John5", BirthDay = new BirthDate(6, 7, 8) });
    }
  }
}

出生日期控件.xaml

<UserControl x:Class="Templates.BirthDateControl"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             mc:Ignorable="d" d:DesignWidth="300" Height="52.273"
             DataContext="{Binding RelativeSource={RelativeSource Self}}"
             >
    <Grid>
        <StackPanel>
        <Label Content="Date:"/>
            <StackPanel Orientation="Horizontal" >
                <TextBox Text="{Binding BirthDayObj.Day}" />
                <TextBox Text="{Binding BirthDayObj.Month}"/>
                <TextBox Text="{Binding BirthDayObj.Year}" />
            </StackPanel>
        </StackPanel>
    </Grid>
</UserControl>

出生日期控件.xaml.cs

namespace Templates
{
  public partial class BirthDateControl : System.Windows.Controls.UserControl
  {
    public static DependencyProperty BirthDayObjProperty =
      DependencyProperty.Register("BirthDayObj", typeof(BirthDate), typeof(BirthDateControl));

    public BirthDate BirthDayObj
    {
      get
      {
        return ((BirthDate)GetValue(BirthDayObjProperty));
      }
      set
      {
        SetValue(BirthDayObjProperty, value);
      }
    }

    public BirthDateControl()
    {
      InitializeComponent();
    }
  }
}

人物.cs

namespace Entities
{
  public class Person : INotifyPropertyChanged
  {
    private string name;
    private int age;
    private BirthDate _birthDay;

    public string Name
    {
      get { return this.name; }
      set { 
        this.name = value;
        this.OnPropertyChanged("Name");
        this.OnPropertyChanged("Description");
      }
    }

    public int Age
    {
      get { return this.age; }
      set
      {
        this.age = value;
        this.OnPropertyChanged("Age");
        this.OnPropertyChanged("Description");
      }
    }

      public string Description
      {
        get { return Name + "_" + Age + "_" + BirthDay.Day; }
      }


    public BirthDate BirthDay
    {
      get { return this._birthDay; }
      set
      {
        this._birthDay = value;
        this.OnPropertyChanged("BirthDate");
        this.OnPropertyChanged("Description");
      }
    }


      public event PropertyChangedEventHandler PropertyChanged;

      protected void OnPropertyChanged(string propName)
      {
        if (this.PropertyChanged != null)
          this.PropertyChanged(
              this, new PropertyChangedEventArgs(propName));
      }
    }
}

出生日期.cs

namespace Entities
{
  public class BirthDate : INotifyPropertyChanged
  {
    private int day;
    private int month;
    private int year;

    public BirthDate(int day, int month, int year)
    {
      this.day = day;
      this.month = month;
      this.year = year;
    }

    public int Day {
      get { return this.day; }
      set
      {
        this.day = value;
        this.OnPropertyChanged("day");
      }
    }

    public int Month {
      get { return this.month; }
      set
      {
        this.month = value;
        this.OnPropertyChanged("month");
      }
    }

    public int Year {
      get { return this.year; }
      set
      {
        this.year = value;
        this.OnPropertyChanged("year");
      }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    protected void OnPropertyChanged(string propName)
    {
      if (this.PropertyChanged != null)
        this.PropertyChanged(
            this, new PropertyChangedEventArgs(propName));
    }
  }
}

如果我运行它,它将显示列,但生日列为空。

没有错误或警告,但这显示在输出中:

System.Windows.Data Error: 40 : BindingExpression path error: 'BirthDay' property not found on 'object' ''DataGrid' (Name='TableDataGrid')'. BindingExpression:Path=BirthDay; DataItem='DataGrid' (Name='TableDataGrid'); target element is 'BirthDateControl' (Name=''); target property is 'BirthDayObj' (type 'BirthDate')
System.Windows.Data Error: 40 : BindingExpression path error: 'BirthDay' property not found on 'object' ''DataGrid' (Name='TableDataGrid')'. BindingExpression:Path=BirthDay; DataItem='DataGrid' (Name='TableDataGrid'); target element is 'BirthDateControl' (Name=''); target property is 'BirthDayObj' (type 'BirthDate')
System.Windows.Data Error: 40 : BindingExpression path error: 'BirthDay' property not found on 'object' ''DataGrid' (Name='TableDataGrid')'. BindingExpression:Path=BirthDay; DataItem='DataGrid' (Name='TableDataGrid'); target element is 'BirthDateControl' (Name=''); target property is 'BirthDayObj' (type 'BirthDate')
System.Windows.Data Error: 40 : BindingExpression path error: 'BirthDay' property not found on 'object' ''DataGrid' (Name='TableDataGrid')'. BindingExpression:Path=BirthDay; DataItem='DataGrid' (Name='TableDataGrid'); target element is 'BirthDateControl' (Name=''); target property is 'BirthDayObj' (type 'BirthDate')
System.Windows.Data Error: 40 : BindingExpression path error: 'BirthDay' property not found on 'object' ''DataGrid' (Name='TableDataGrid')'. BindingExpression:Path=BirthDay; DataItem='DataGrid' (Name='TableDataGrid'); target element is 'BirthDateControl' (Name=''); target property is 'BirthDayObj' (type 'BirthDate')
System.Windows.Data Error: 40 : BindingExpression path error: 'BirthDay' property not found on 'object' ''DataGrid' (Name='TableDataGrid')'. BindingExpression:Path=BirthDay; DataItem='DataGrid' (Name='TableDataGrid'); target element is 'BirthDateControl' (Name=''); target property is 'BirthDayObj' (type 'BirthDate')
'WpfTemplatesDemo3.exe' (Managed (v4.0.30319)): Loaded 'C:\Windows\Microsoft.Net\assembly\GAC_MSIL\UIAutomationTypes\v4.0_4.0.0.0__31bf3856ad364e35\UIAutomationTypes.dll', Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
System.Windows.Data Error: 40 : BindingExpression path error: 'BirthDay' property not found on 'object' ''DataGrid' (Name='TableDataGrid')'. BindingExpression:Path=BirthDay; DataItem='DataGrid' (Name='TableDataGrid'); target element is 'BirthDateControl' (Name=''); target property is 'BirthDayObj' (type 'BirthDate')
The program '[16364] WpfTemplatesDemo3.exe: Managed (v4.0.30319)' has exited with code 0 (0x0).

我不明白为什么它不将数据绑定到用户控件。


The DataGridRowDataContext of Person目的。这DataContext是在你们之间遗传的VisualTree,因此您的 UC 具有相同的上下文。要使您的示例正常工作:

  1. 丢弃BirthDayObjProperty来自你的加州大学。
  2. 把这条线从你的DataGrid: DataContext="{Binding UpdateSourceTrigger=PropertyChanged}"
  3. 在你的 UC 中扔掉这一行:DataContext="{Binding RelativeSource={RelativeSource Self}}"
  4. 您的 UC 绑定可以非常简单:

    <Grid>
        <StackPanel>
            <Label Content="Date:"/>
            <StackPanel Orientation="Horizontal" >
                <TextBox Text="{Binding BirthDay.Day}" />
                <TextBox Text="{Binding BirthDay.Month}"/>
                <TextBox Text="{Binding BirthDay.Year}" />
            </StackPanel>
        </StackPanel>
    </Grid>
    
  5. 阅读更多关于DataContext一般而言,继承和绑定, 因为你显然滥用了它们。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在 WPF 中绑定用户控件作为 DataGridTemplateColumn 失败 的相关文章

  • MVVM:来自 FileOpenPicker 的图像绑定源

    我将 OnActivated 添加到 app xaml cs 中 它可以正常工作 protected async override void OnActivated IActivatedEventArgs args var continua
  • 处理器关联组 C#

    我使用的是 72 核的 Windows Server 2016 我看到有两组处理器 我的 net 应用程序将使用一个或其他组 我需要能够强制我的应用程序使用我选择的组 我看到下面的代码示例 但我无法使其工作 我可能传递了错误的变量 我希望应
  • 为类型列表创建别名并将其作为模板参数传递

    我正在使用可变参数模板来实现访问者模式 template
  • 字符串/分段错误

    Program to calculate trip and plan flights define TRIP 6 define NAMEMAX 40 define DEST 1 include
  • 如何反序列化 XML 文档

    如何反序列化此 XML 文档
  • 以编程方式更新 Wifi 网络

    我正在尝试创建一个程序 当某个 wifi 网络在范围内时 该程序会连接到该网络 即使已经连接到另一个 wifi 也是如此 我在用着简单Wifi https github com DigiExam simplewifi 基本上效果很好 除了在
  • 图片框、双击和单击事件

    我有一个奇怪的问题 我有一个图片框双击事件以及单击事件 问题是即使我双击该控件 也会引发单击事件 如果我禁用单击事件 则双击事件正在工作 这个问题已经在这里讨论过 https stackoverflow com questions 1830
  • R 包与 Rcpp 的链接错误:“未定义符号:LAPACKE_dgels”

    我正在创建一个 R 包 lapacker 以使用 R API 头文件 R ext Lapack h 为 R 提供和使用的内部 LAPACK 库 仅具有双精度和双复数 提供 C 接口 源代码 https github com ypan1988
  • 将两个垂直滚动条相互绑定

    我在控件中有两个 TextBox 并且它们都有两个 VerticalScrollBar 我想在它们之间绑定 VerticalScrollBars 如果一个向上 第二个也会向上等等 如果可以的话我该怎么做 Thanks 不是真正的绑定 但它有
  • 我想找到 C# 代码中所有后面没有括号的 if 语句。通过正则表达式

    我想找到所有if声明和for后面没有大括号的语句 当你在一个文件中写入一行时if声明您大多不会将其括在大括号中 所以我想找到所有这些if and for声明 请帮忙 就像我想捕捉这个声明 if childNode Name B return
  • 绑定集合的子集

    我有一个ObservableCollection
  • 来自同一基模板类的 C++ 重写函数,具有多重继承不明确的函数调用

    我需要打电话init int iNumber 从基类派生的函数 基类 h pragma once include stdafx h template
  • Qt 多重继承和信号

    由于 QObject 我在 QT 中遇到了有关多重继承的问题 我知道很多人也有同样的问题 但我不知道该如何解决 class NavigatableItem public QObject Q OBJECT signals void desel
  • ArrayList 有什么问题?

    最近我问了一个关于 SO 的问题 其中提到了可能使用 c ArrayList 来解决问题 有人评论说使用数组列表不好 我想了解更多有关此的信息 我以前从未听说过关于数组列表的这种说法 有人可以带我了解使用数组列表可能出现的性能问题吗 C n
  • 结构大小与 typedef 版本不同?

    我的代码中有以下结构声明和 typedef struct blockHeaderStruct bool allocated unsigned int length typedef struct blockHeaderStruct block
  • 在 C 中运行 setuid 程序的正确方法

    我有一个权限为4750的进程 我的Linux系统中存在两个用户 root 用户和 appz 用户 该进程继承以 appz 用户身份运行的进程管理器的权限 我有两个基本惯例 void do root void int status statu
  • 使用属性和性能

    我正在优化我的代码 我注意到使用属性 甚至自动属性 对执行时间有深远的影响 请参阅下面的示例 Test public void GetterVsField PropertyTest propertyTest new PropertyTest
  • 在for循环中声明和初始化变量

    可以简单写一下吗 for int i 0 代替 int i for i 0 在 C 或 C 中 并且会变量i只能在循环内部访问 它在 C 中有效 它在 C 的原始版本中是不合法的 但在 C99 中被采用为 C 的一部分 当时一些 C 功能被
  • 将二进制长字符串转换为十六进制 C#

    我正在寻找一种将长二进制字符串转换为十六进制字符串的方法 二进制字符串看起来像这样 0110011010010111001001110101011100110100001101101000011001010110001101101011 我
  • 如何将 ValueConverter 应用于基于约定的 Caliburn.Micro 绑定?

    如何将 ValueConverter 应用于基于约定的 Caliburn Micro 绑定 或者您需要使用 Binding 语法吗 我知道我可以做到这一点

随机推荐