C # WPF, как обновить наблюдаемую коллекцию после программного обновления сетки данных - нет MVVM - PullRequest
0 голосов
/ 08 января 2019

У меня есть сетка данных, связанная с наблюдаемой коллекцией. У них есть большое количество столбцов / свойств, с которыми мне приходится работать. Мне нужно сделать замену строки в столбце, выбранном пользователем во время выполнения через выпадающий список. enter image description here Итак, сначала я выясняю индекс столбца (в нашем случае Description index = 2, начиная с 0), а затем выполняю подстановки с помощью приведенного ниже кода. Переменная iii указывает текущую строку

DataGridRow row = (DataGridRow)dtgFeatures.ItemContainerGenerator.ContainerFromIndex(iii);
if (row != null)
{
    var content = dtgFeatures.Columns[indexColumnToOperateOn].GetCellContent(row);
    if (content != null)
    {
        string str = ((TextBlock)content).Text;
        if (str.ToUpper().Trim().Contains(tbxSrc.Text.ToUpper().Trim()))
        {
            ((TextBlock)content).Text = str.Replace(tbxSrc.Text, tbxDest.Text);
            obcCfgPartPrograms = (ObservableCollection < CfgPartPrograms >) dtgFeatures.ItemsSource;
        }
    }
}

В нашем примере мы можем изменить строку «pcacd» на «AAA»

enter image description here

enter image description here

Так что «графически» работает, но наблюдаемая коллекция не обновляется с помощью команды obcCfgPartPrograms = (ObservableCollection ) dtgFeatures.ItemsSource;

Я знаю, что могу сделать это через каждое свойство, но это было бы неприятно для

- EDIT - Извините от комментариев, которые я вижу, я не дал понять, Мой плохой.

Итак, у меня очень большое количество свойств (здесь 9, но, возможно, много, много других), поэтому я бы не писал что-то вроде:

if(comboBoxValue="Description")
    obc.Description = dtgFeatures[2,row];
else  if(comboBoxValue="Notes")
    obc.Description = dtgFeatures[4,row];

...

Поскольку я могу вручную отредактировать сетку данных и отразить изменения в наблюдаемой коллекции

datagrid РУЧНОЕ РЕДАКТИРОВАНИЕ ---> изменения в наблюдаемой коллекции

почему бы не иметь возможности ПРОГРАММНО (например, со сравнением строк) отредактировать сетку данных и отразить изменения на объекте?

datagrid АВТОМАТИЧЕСКОЕ РЕДАКТИРОВАНИЕ ---> изменения в наблюдаемой коллекции

Итак, вкратце: 1. Я могу изменить сетку данных -> dtgFeatures [property_X, row_Y] = "AAAAAA"; 2. Я хотел бы иметь возможность автоматически изменять obc [Y] .X = "AAAAAA";

их очень много.

Спасибо за любую помощь Patrick

Ответы [ 3 ]

0 голосов
/ 08 января 2019

Если TextBlock связан со свойством источника объекта CfgPartPrograms, вы можете получить имя этого свойства, используя метод GetBindingExpression. Затем вы можете использовать отражение, чтобы установить для свойства новое значение:

DataGridRow row = (DataGridRow)dtgFeatures.ItemContainerGenerator.ContainerFromIndex(iii);
if (row != null)
{
    var content = dtgFeatures.Columns[indexColumnToOperateOn].GetCellContent(row);
    if (content != null)
    {
        TextBlock textBlock = (TextBlock)content;
        if (textBlock.Text.ToUpper().Trim().Contains(tbxSrc.Text.ToUpper().Trim()))
        {
            string str = textBlock.Text.Replace(tbxSrc.Text, tbxDest.Text);
            textBlock.Text = str;
            BindingExpression be = textBlock.GetBindingExpression(TextBlock.TextProperty);
            if (be != null && be.ParentBinding != null && be.ParentBinding.Path != null && !string.IsNullOrEmpty(be.ParentBinding.Path.Path))
            {
                object cfgPartPrograms = textBlock.DataContext;
                if (cfgPartPrograms != null)
                {
                    System.Reflection.PropertyInfo pi = typeof(CfgPartPrograms).GetProperty(be.ParentBinding.Path.Path);
                    if (pi != null)
                        pi.SetValue(cfgPartPrograms, str);
                }
            }
        }
    }
}
0 голосов
/ 08 января 2019

Да, это можно сделать. Путь, по которому нужно пройти, следующий:

представьте себе следующий класс:

public class MyClass
{
    public string s1 { get; set; }
    public string s2 { get; set; }
    public string s3 { get; set; }

    public MyClass(string _s1, string _s2, string _s3)
    {
        s1 = _s1;
        s2 = _s2;
        s3 = _s3;
    }
}

Итак, теперь мы можем создать и заполнить объект:

var obc = new ObservableCollection<MyClass>();
obc.Add(new MyClass("a1","a2","a3"));
obc.Add(new MyClass("b1", "b2","b3"));

enter image description here

Мы можем изменить его с помощью:

foreach (var itemObc in obc)
{
    PropertyInfo[] Fields = itemObc.GetType().GetProperties();
        foreach (PropertyInfo field in Fields)
    {
    var currentField = field.GetValue(itemObc, null);
    var t = currentField.GetType();
    if (t == typeof(string))
        field.SetValue(itemObc, "XXXX");
    }
}

и результат:

enter image description here

Вы можете даже использовать расширения:

public static class ObservableCollectionExtensions
{
public static ObservableCollection<T> SetValue<T>(this ObservableCollection<T> obc, int rowNumFromZero, int propNumFromZero, string str)
{
    int rowCounter = -1;
    foreach (var itemObc in obc)
    {
        rowCounter++;
        PropertyInfo[] Fields = itemObc.GetType().GetProperties();
        int propCounter = -1;
        foreach (PropertyInfo field in Fields)
        {
            propCounter++;
            if (rowCounter == rowNumFromZero)
            {
                var currentField = field.GetValue(itemObc, null);
                if (currentField != null)
                {
                    var t = currentField.GetType();
                    if (t == typeof(string) && propCounter == propNumFromZero)
                        field.SetValue(itemObc, str);
                }
            }
        }
    }
    return obc;
}

}

и используйте это так:

obc.SetValue (numRow, numCol, strNewValue);

0 голосов
/ 08 января 2019

Вместо этого вам следует изменить данные в ObservableCollection. Как правило, всегда избегайте манипуляций с элементами управления пользовательского интерфейса. Измените ваши данные и, если необходимо, вызовите событие OnPropertyChanged.

...