【问题标题】:Complex object Header Binding issue in a DataGridDataGrid中的复杂对象标题绑定问题
【发布时间】:2018-02-28 01:49:56
【问题描述】:

听起来很像其他关于绑定标题的问题 - 但通常它们是关于简单的标题,如 TextBoxes....

我的标题需要使用一个对象实例化,其中包含多个图像和文本组件,称为 EMSPlanViewDeviceNew。这有一个名为 TheDeviceProperty 的 DP,它保存设备的所有数据。

这就是我设置列标题的方式

DataGridTemplateColumn  TextColumn2 = new DataGridTemplateColumn();
FrameworkElementFactory TextBorder2 = new FrameworkElementFactory(typeof(EMSTextCell));
FrameworkElementFactory TextBlock2  = new FrameworkElementFactory(typeof(TextBlock));

ImageTemplate              = new DataTemplate();
TextColumn2.CellTemplate   = ImageTemplate;

// Setup a Header Template to use for the backup paths column
System.Windows.DataTemplate BackupHeaderTemplate  = new System.Windows.DataTemplate();
Binding HeaderBinding        = new Binding("BackupPaths[" + index.ToString() + "].BackupDevice");

FrameworkElementFactory MVDeviceColumnHeader = new FrameworkElementFactory(typeof(EMSPlanViewDeviceNew));
MVDeviceColumnHeader.SetValue(EMSPlanViewDeviceNew.HeightProperty, (double)60);
MVDeviceColumnHeader.SetValue(EMSPlanViewDeviceNew.WidthProperty, (double)85);
MVDeviceColumnHeader.SetValue(EMSPlanViewDeviceNew.TheDeviceProperty, HeaderBinding);

BackupHeaderTemplate.VisualTree = MVDeviceColumnHeader;

TextColumn2.HeaderTemplate = BackupHeaderTemplate;

Dataset 包含具有 BackupDevice、BackupStatus 和 BackupLevel 属性的 BackupPaths 列表。在运行时,填充了网格并绘制了标题对象,但是标题对象没有显示正确的数据,只是默认值,所以这告诉我绑定没有正确连接到数据集,或者它只是在这样就不会调用对象中的“UpdateVisuals”方法,因此不会用正确的数据重绘标题。 我在这里看到的解决方案建议使用 HeaderTemplate,但我认为我正在这样做,所以我不确定还有什么可以尝试让它触发绑定。

这是它在运行时的样子

标题行对象应与第一列图像相同。

谁能建议我还需要做什么来纠正我的错误。谢谢。

public class BackupDataSet

{ 私人字符串_TheAddress; 公共字符串 TheAddress { 得到 { 返回 _TheAddress; } 设置 { _TheAddress = 值; } }

private EMSDevices.EMSBasicDevice _TheDevice;
public EMSDevices.EMSBasicDevice TheDevice
{
    get { return _TheDevice; }
    set { _TheDevice = value; }
}

private BitmapImage _DeviceIcon;
public BitmapImage  DeviceIcon
{
    get { return _DeviceIcon; }
    set { _DeviceIcon = value; }
}

private string _TheIdent;
public string  TheIdent
{
    get { return _TheIdent; }
    set { _TheIdent = value; }
}

private string _TheMainSignalPath;
public string  TheMainSignalPath
{
    get { return _TheMainSignalPath; }
    set { _TheMainSignalPath = value; }
}

public string BackupPathsCount
{
    get
    {
        if (CountGoodBackupPaths() > 0)
            return CountGoodBackupPaths().ToString();
        else if (CountLowBackupPaths() > 0)
            return (-1 * CountLowBackupPaths()).ToString();
        else
            return "--";
    }
}

private List<EMSDevices.EMSBackupPath> _BackupPaths;
public List<EMSDevices.EMSBackupPath>  BackupPaths
{
    get { return _BackupPaths; }
    set { _BackupPaths = value; }
}

public void AddBackupPath(EMSDevices.EMSBasicDevice backupDevice, EMSDevices.SignalSetting backupStatus, int backupLevel)
{
    EMSDevices.EMSBackupPath NewBackupPath = new EMSDevices.EMSBackupPath(backupDevice, backupStatus, backupLevel);

    _BackupPaths.Add(NewBackupPath);
}

public BackupDataSet(string address, BitmapImage icon, string ident, string mainsignalpath)
{
    _TheAddress        = address;
    _DeviceIcon        = icon;
    _TheIdent          = ident;
    _TheMainSignalPath = mainsignalpath;

    _BackupPaths       = new List<EMSDevices.EMSBackupPath>();
}

public BackupDataSet(EMSDevices.EMSBasicDevice device)
{
    _TheAddress        = device.TheAddress;
    _TheDevice         = device.Clone();
    _TheMainSignalPath = device.TheMainSignalPath;

    _BackupPaths       = new List<EMSDevices.EMSBackupPath>();
}

public int CountGoodBackupPaths()
{
    List<EMSDevices.EMSBackupPath> Paths = new List<EMSDevices.EMSBackupPath>();

    Paths = (from BackupPath in _BackupPaths
                where BackupPath.BackupStatus == EMSDevices.SignalSetting.GoodSignal
                select BackupPath).ToList();

    return Paths.Count;
}

public int CountLowBackupPaths()
{
    List<EMSDevices.EMSBackupPath> Paths = new List<EMSDevices.EMSBackupPath>();

    Paths = (from BackupPath in _BackupPaths
                where BackupPath.BackupStatus == EMSDevices.SignalSetting.LowSignal
                select BackupPath).ToList();

    return Paths.Count;
}

}

这是数据集的填充方式:

if (AllCIEDevices.Count > 0)

{ CIEDataSet = new List();

foreach(EMSDevices.EMSBasicDevice dev1 in AllCIEDevices)
{
    BackupDataSet dataset = new BackupDataSet(dev1);

    foreach(EMSDevices.EMSBackupPath backup in dev1.BackupPaths)
    {
        dataset.AddBackupPath(backup.BackupDevice, backup.BackupStatus, backup.BackupLevel);
    }
    CIEDataSet.Add(dataset);
}
// Setup the grid for devices that have the CIE as the parent
PanelDeviceView.ItemsSource   = CIEDataSet; 
SetupDataGrid(PanelDeviceView, Headers);

}

所以 DataGrid 已经通过 PanelDeviceView.ItemSource 连接了数据集。

每一行数据都有一个设备、一些其他参数和一个备份路径列表。

【问题讨论】:

  • BackupPaths 属性在哪里定义?
  • BackupPaths 是一个名为 BackupDataSet 的类的属性:
  • 这个类是如何以及在哪里使用的?
  • 私人列表 _BackupPaths;公共列表 BackupPaths { get { return _BackupPaths; } 设置 { _BackupPaths = 值; } }
  • 这里有人有什么想法吗?或者这是一个死鸭子,我需要找到另一种方法来解决这个问题?

标签: c# wpf datagrid


【解决方案1】:

BindingSource属性设置为定义BackupPaths属性的对象:

Binding HeaderBinding = new Binding("BackupPaths[" + index.ToString() + "].BackupDevice") { Source = this };

【讨论】:

  • 感谢您的建议.....不幸的是它不起作用。列数据使用相同的技术来访问要显示的数据,因此数据单元格被正确填充......但标题没有。我现在想知道这个问题是否与每个行数据(附加到网格的数据集中的一个条目)本质上重复标题数据这一事实无关,也许这会混淆这个过程。也许我需要将标头数据与数据集分开传递,并手动绑定到该数据集,因此它只获取一份标头变量副本,而不是每行一个(如果这有任何意义!)
  • 这似乎是个死鸭子……也许真的做不到,或者至少,论坛上的任何人都做不到……
  • 感谢您迄今为止的帮助。我相信通过不尝试将标头绑定到主数据上下文中的对象而是尝试将标头绑定到仅包含标头的单独对象数组来找到解决方案。我的想法的原因是,当每一行都被填充时,它会为标题提供另一个数据集,这不是所需要的,因为所有数据行只有一个标题行。和以前一样,该行数据已正确绑定,但标题行未正确绑定。当我尝试了我的想法后,我会回来的!
  • 你可以绑定到任何你想要的对象。只需确保将绑定的 Source 属性设置为该对象,就像我在回答中所做的那样。
  • 确实....但是哪个“对象”是“这个”? DataGrid,数据源,数据行?据我了解,使用“this”是指容器对象,即类(在我的情况下)EMS_BackupPathControl,其中有一个 DataGrid,它的数据源设置为一个 BackupDataSet 列表,每个列表都包含每个可能的备份路径...(是的,这很复杂!)。所以很难知道“这个”需要是哪个,但我猜它是数据集,或者可能是数据网格?那么如何在“Source”语句中指定呢???
猜你喜欢
  • 1970-01-01
  • 2011-12-25
  • 1970-01-01
  • 2015-01-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多