Проблема: < /p>
Даже если мой вывод отладки подтверждает, что, например, «Операции DFL Defillet Line Outfeed.doc» найден для работника (и его нормализованный ключ присутствует в словаре со статусом = «✔»), сетка по-прежнему показывает кросс. Also, I keep getting binding errors such as:
"BindingExpression path error: 'Status' property not found on 'MyNamespace.CasualEmployeeSkill'"
"BindingExpression path error: 'FilePath' property not found on 'MyNamespace.CasualEmployeeSkill'"
It appears that the binding isn’t reaching the Значение словаря (SopstatusEntry), но вместо этого пытается найти «статус» или «FilePath» на самом объекте сотрудника.
Код: Выделить всё
public class SOPStatusEntry
{
public string Status { get; set; } = "❌"; // Default value
public string FilePath { get; set; } = string.Empty; // Path to the file if available
}
public class CasualEmployeeSkill : INotifyPropertyChanged
{
public string EmployeeName { get; set; }
// Dictionary mapping normalized SOP names to their status entry
private Dictionary _sopStatus = new Dictionary();
public Dictionary SOPStatus
{
get => _sopStatus;
set { _sopStatus = value; OnPropertyChanged(nameof(SOPStatus)); }
}
public event PropertyChangedEventHandler PropertyChanged;
public void NotifySOPStatusChanged() => OnPropertyChanged(nameof(SOPStatus));
protected void OnPropertyChanged(string propertyName) =>
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
< /code>
Динамическое создание столбцов в Code-behind: < /p>
// For each master SOP, add a column so that the cell’s DataContext is the dictionary value.
foreach (var sop in MasterSOPs)
{
string columnName = Normalize(sop.Name);
SkillMatrixGrid.Columns.Add(new Syncfusion.UI.Xaml.DataGrid.GridTemplateColumn
{
// IMPORTANT: Set MappingName to "SOPStatus[normalizedKey]"
MappingName = $"SOPStatus[{columnName}]",
HeaderText = sop.Name,
HeaderTemplate = (DataTemplate)this.Resources["SOPHeaderTemplate"],
CellTemplate = (DataTemplate)this.Resources["SOPCellTemplate"]
});
}
< /code>
Пример шаблона ячейки XAML: < /p>
< /code>
преобразователи (упрощенные примеры): < /p>
public class ButtonVisibilityConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, string language)
{
if (value is string status)
return status == "✔" ? Visibility.Visible : Visibility.Collapsed;
return Visibility.Collapsed;
}
public object ConvertBack(object value, Type targetType, object parameter, string language)
{
throw new NotImplementedException();
}
}
public class TextVisibilityConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, string language)
{
if (value is string status)
return status == "✔" ? Visibility.Collapsed : Visibility.Visible;
return Visibility.Visible;
}
public object ConvertBack(object value, Type targetType, object parameter, string language)
{
throw new NotImplementedException();
}
}
< /code>
Ключевые точки: < /p>
Словарь Привязка:
Столочное сопоставление столбца должно быть установлено так, чтобы дата -образный данных ячейки - это значение словаря (экземпляр SopstatusEntry). Обратите внимание, что в приведенном выше коде мы используем:
mappingName = $ "sopstatus [{columnname}]"
(не добавляйте «.status» в mappingName.) Это работает, потому что DataContext для каждой ячейки является словарным значением от Sopstatus. < /P>
Динамическая клавиша:
Нормализованное имя SOP (рассчитывается в коде-гибкости с помощью метода Normalize ()) используется в качестве ключа для каждой записи словаря. Этот ключ должен точно соответствовать определению динамического столбца и словарным заполненным для каждого сотрудника. Установив имя Mapping -Name без «.status», дата -обратный контекст ячейки становится правильным SopstatusEntry. (Например, если нормализованный ключ - «siteforkliftgeneraldoc», то связывание в шаблоне клетки должно быть разрешено с Sopstatusentry, соответствующим Sopstatus [»siteforkliftgeneraldoc"]). < /P>
мой вопрос:
Несмотря на то, что нанесение картирования правильного и подсчета Я до сих пор вижу такие ошибки, как «Ошибка пути BindingExpression:« Статус », не найденное в« CasualEmployeSkill ». Кажется, что привязка неправильно улавливает словарное значение. Кто -нибудь столкнулся с этой проблемой? Как я могу гарантировать, что динамическая сетка связывается с значением словаря (sopstatusentry), а не с родительским объектом сотрудника? Например, я попытался использовать привязки, такие как: < /p>
< /code>
Я ожидал, что сетка отобразит тик, если папка SOP сотрудника содержала файл, который слабо соответствует имени Master SOP, и в противном случае крест. Когда тик отображается, нажав на него, следует открыть файл. Несмотря на многочисленные попытки (и даже пробующие динамические ключи), я непрерывно получаю ошибки привязки, в которых кажется, что привязывающий двигатель ищет свойства «статус» и «FilePath» на объекте сотрудника, а не на запись в словаре (Sopstatus), связанные с каждой SOP. MappingName в коде-блудении), но ошибка сохраняется. Любая помощь в правильной связке с свойством динамического словаря и кнопкой ячейки видимой только тогда, когда статус SOP является тик (и для прохождения пути файла) будет очень оценена. /> mainpage.xaml
x:Class="Test.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:syncfusion="using:Syncfusion.UI.Xaml.DataGrid"
xmlns:local="using:Test">
< /code>
mainpage.xaml.cs
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Data;
using System.Collections.ObjectModel;
using System.Collections.Generic;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Linq;
using System.Text.RegularExpressions;
namespace Test
{
public sealed partial class MainPage : Page
{
public ObservableCollection Employees { get; set; } = new ObservableCollection();
public List MasterSOPs { get; set; } = new List
{
"SOP1",
"SOP2"
};
public MainPage()
{
this.InitializeComponent();
LoadData();
}
private void LoadData()
{
// create a test employee.
var emp = new Employee { EmployeeName = "John Doe" };
// Populate the employee's dictionary for each master SOP.
foreach (var sop in MasterSOPs)
{
string key = Normalize(sop);
// For testing John Doe has SOP1 ("✔") and not SOP2 ("❌").
emp.SOPStatus[key] = new SOPStatusEntry
{
Status = sop == MasterSOPs.First() ? "✔" : "❌",
FilePath = sop == MasterSOPs.First() ? @"C:\Test\TestFile.doc" : string.Empty
};
}
Employees.Add(emp);
// Set up grid columns.
MyDataGrid.Columns.Clear();
// Add Employee Name column.
MyDataGrid.Columns.Add(new Syncfusion.UI.Xaml.DataGrid.GridTextColumn
{
MappingName = "EmployeeName",
HeaderText = "Employee Name",
Width = 200
});
// For each master SOP, add a column.
foreach (var sop in MasterSOPs)
{
string key = Normalize(sop);
MyDataGrid.Columns.Add(new Syncfusion.UI.Xaml.DataGrid.GridTemplateColumn
{
MappingName = $"SOPStatus[{key}]", // MappingName to dictionary entry
HeaderText = sop,
CellTemplate = (DataTemplate)this.Resources["SOPCellTemplate"]
});
}
// Bind the collection to the grid.
MyDataGrid.ItemsSource = Employees;
}
private string Normalize(string input) =>
Regex.Replace(input, @"[^a-zA-Z0-9]", "").ToLower();
}
// Employee model.
public class Employee : INotifyPropertyChanged
{
public string EmployeeName { get; set; }
// Dictionary mapping normalized SOP names to SOPStatusEntry.
private Dictionary _sopStatus = new Dictionary();
public Dictionary SOPStatus
{
get => _sopStatus;
set { _sopStatus = value; OnPropertyChanged(); }
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged([CallerMemberName] string name = null) =>
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
// Represents the status of an SOP.
public class SOPStatusEntry
{
public string Status { get; set; } // "✔" if present, "❌" if missing
public string FilePath { get; set; } // File path if available
}
// Converters to show/hide button or text depending on status.
public class ButtonVisibilityConverter : IValueConverter
{
public object Convert(object value, System.Type targetType, object parameter, string language)
{
return value is string status && status == "✔" ? Visibility.Visible : Visibility.Collapsed;
}
public object ConvertBack(object value, System.Type targetType, object parameter, string language)
{
throw new System.NotImplementedException();
}
}
public class TextVisibilityConverter : IValueConverter
{
public object Convert(object value, System.Type targetType, object parameter, string language)
{
return value is string status && status == "✔" ? Visibility.Collapsed : Visibility.Visible;
}
public object ConvertBack(object value, System.Type targetType, object parameter, string language)
{
throw new System.NotImplementedException();
}
}
}
Подробнее здесь: https://stackoverflow.com/questions/794 ... 3-datagrid