Как я могу обновить WinForms TreeView, когда помеченные объекты меняются? - PullRequest
0 голосов
/ 27 февраля 2019

У меня есть WinForms TreeView для представления данных моего калькулятора.Когда я читаю свои данные, я создаю свой TreeView и помечаю каждый узел TreeView соответствующим объектом.Ниже приведен пример TreeView.

SUM
    SUM
        TIMES
            UnitsSold
            UnitPrice
        IncomeFromContracts
    NEGATIVE SUM
        Rent
        Wages
        TIMES
            UnitsSold
            UnitMaterialCost

Я создаю TreeView из структуры данных, такой как:

class Operand {
    bool IsNegated {get; set;}
}

class Operator : Operand {
    enum OperatorEnum { SUM, DIFFERENCE, TIMES }
    OperatorEnum MyEnum {get; set;}
    IList<Operand> Children {get; set;}
}

class VariableName : Operand {
    string Name {get; set;}
}

Каждый TreeNode помечен соответствующим операндом.Когда элемент в TreeView выбран, помеченный элемент отображается на панели, чтобы вы могли изменить его свойства.Например, когда я выбираю элемент, вы получаете флажок, в котором вы можете установить значение IsNegated.Я успешно связал этот элемент управления с объектом «Операнд», используя:

negateCheckBox.DataBindings.Add("Checked", requirementTree.SelectedNode.Tag, "IsNegated");

Нажатие на флажок соответствующим образом обновляет базовые данные, но это не заставляет TreeView обновлять свои данные, поэтому даже если возвращаемое значениеметод ToString () элемента изменился (теперь к нему добавлен префикс «NEGATIVE»), поскольку TreeNode уже создан с этой строкой, он не обновляется.

У меня также есть некоторые «Add» и «Remove»»кнопки, которые создают дополнительные узлы в TreeView и удаляют их, но все они работают вручную - обновляют базовые структуры данных, а затем перестраивают весь TreeView (это приводит к обновлению представления, поэтому я могу проверить, работают ли другие мои привязки).

Какие шаги мне нужно предпринять, чтобы TreeView не заполнялся вручную, а был полностью привязан к моей структуре данных, чтобы такие изменения сразу же отражались?Кажется, что существует множество способов связать данные в WinForms, и мне неясно, какие из них применимы в каких ситуациях.

Большое спасибо за помощь!

1 Ответ

0 голосов
/ 27 февраля 2019

Основываясь на замечании Резы о том, что привязка данных не поддерживается для TreeView, я нашел разумный обходной путь.

Каждый класс "model" реализует INotifyPropertyChanged и вызывает событие при изменении любого из его свойств.

class Operand : INotifyPropertyChanged
{
    public bool IsNegated
    {
        get { return m_isNegated; }
        set { m_isNegated = value; RaisePropertyChanged(); }
    }
    private bool m_isNegated = false;

    private void RaisePropertyChanged([CallerMemberName]string prop = "")
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(prop));
    }
}

Затем я добавил фиктивный контроллер, который связывает модель с узлом TreeView:

public class OperandTreeNodeController

{
    private Requirement m_model;
    private TreeNode m_view;

    public OperandTreeNodeController(Requirement model, TreeNode view)
    {
        m_model = model;
        m_view = view;

        m_model.PropertyChanged += Model_PropertyChanged;
    }

    private void Model_PropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        m_view.Text = m_model.ToString();
    }
}

Теперь, когда я создаю TreeNode, я также создаю контроллер.Здесь есть небольшая утечка памяти, потому что они могут продолжать создаваться и добавляться к событию PropertyChanged модели, и сборщик мусора может никогда не очистить их, но я обработал это вручную в своем коде, добавив функцию Destroy ()и отслеживание / уничтожение их вручную.

Похоже, что это достигнет большинства моих целей, поэтому я буду придерживаться этого, если у кого-то нет другой идеи.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...