Привязка данных Winforms и INotifyPropertyChanged на моно

Я сделал свое первое моно-приложение, работающее на Raspberry Pi. Проблема в том, что привязка данных не обновляла пользовательский интерфейс. Чтобы быть более конкретным, событие PropertyChanged внутри моего контроллера / модели имеет значение NULL. Значит, подписчика нет.

Когда я запускаю приложение в Windows внутри отладчика Visual Studio, пользовательский интерфейс обновляется должным образом.

Моно версия: 4.6.2 ОС: Raspbian Wheezy .NET: 4.5

Я нашел немного информации по этому сценарию. Поскольку он работает в Windows, а моно поддерживает интерфейс INotifyPropertyChanged, я предположил, что он также будет работать в моно в Linux.

// creating the binding in code dhtControl.labelName.DataBindings.Add("Text", dht, "Name");

Я думаю, что другого кода не требуется, поскольку это реализация INotifyPropertyChanged по умолчанию. Единственное отличие состоит в том, что я передаю модели Action (control.Invoke), чтобы вызвать обновление в основном потоке.

С Уважением


person csteinmueller    schedule 12.02.2017    source источник
comment
Вы в конце концов поняли это? Я столкнулся с той же проблемой.   -  person Kohanz    schedule 08.05.2017
comment
Я понял, что при добавлении привязок данных они не регистрируются в PropertyChangedEvent с помощью Mono, но они регистрируются с .Net. Все еще не знаю почему.   -  person soulsource    schedule 23.06.2017


Ответы (2)


У меня та же проблема, я решил добавить событие действия, запущенное ViewModel, где обновите все элементы управления:

internal void InvokeUIControl(Action action)
    {
        // Call the provided action on the UI Thread using Control.Invoke() does not work in MONO
        //this.Invoke(action);

        // do it manually
        this.lblTemp.Invoke(new Action(() => this.lblTemp.Text = ((MainViewModel)(((Delegate)(action)).Target)).Temperature));
        this.lblTime.Invoke(new Action(() => this.lblTime.Text = ((MainViewModel)(((Delegate)(action)).Target)).Clock));           
    }
person Lucia Minerba    schedule 15.08.2017

Я заметил разницу между .NET и Mono, и у меня возникла та же проблема. После сравнения исходного кода .NET и Mono сначала выясняется, что если вы хотите получить уведомление propertyName в ViewForm любой Control.TextChanged, вам сначала нужно в своей модели:

    public event PropertyChangedEventHandler PropertyChanged;
    public event EventHandler TextChanged;

    protected void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
    {
        if (PropertyChanged != null)
        {
            if (propertyName == "Text")
            {
                TextChanged?.Invoke(this, EventArgs.Empty);
            }
        }
    }

Важно, чтобы обработчик события назывался «TextChanged», чтобы уведомлять TextChanged. Тогда еще в вашей модели вы можете установить:

    private string _Text = "";
    public string Text {
        get {
            return _Text;
        }
        set {
            if (_Text != value) {
                NotifyPropertyChanged ("Text");
            }
        }
    }

А теперь, на ваш взгляд, вы можете сделать что-то подобное.

using System;
using System.ComponentModel;
using System.Windows.Forms;

namespace EventStringTest
{
    public partial class Form1 : Form
    {
        Model md = Model.Instance;

        public Form1()
        {
            InitializeComponent();
            textBox1.DataBindings.Add("Text", md, "Text", false
                , DataSourceUpdateMode.OnPropertyChanged);
            this.OnBindingContextChanged(EventArgs.Empty);
            textBox1.TextChanged += (object sender, System.EventArgs e) => { };
        }

        private void Form1_Load(object sender, EventArgs evt)
        {
            md.PropertyChanged += (object s, PropertyChangedEventArgs e) => { };

            // This is just to start make Text Changed in Model.
            md.TimerGO ();
        }
    }
}

Кажется, что кода много, но я все еще ищу элегантное, даже лучшее решение.

person HyperThread    schedule 23.02.2018