Mono上的Winforms数据绑定和INotifyPropertyChanged

vaj7vani  于 2023-01-14  发布在  其他
关注(0)|答案(3)|浏览(127)

我制作了第一个运行在raspberry pi上的mono应用程序。问题是数据绑定没有更新UI。更具体地说,我的控制器/模型中的PropertyChanged事件为null。这意味着没有订阅者。
当我在visual studio调试器内部的windows上运行应用程序时,ui得到了正确的更新。
单声道版本:4.6.2操作系统:Raspbian Wheezy .NET:4.5
我没有找到太多关于这个场景的信息,因为它可以在windows上运行,并且mono支持INotifyPropertyChanged接口,所以我假设它也可以在linux上的mono上运行。
// creating the binding in code dhtControl.labelName.DataBindings.Add("Text", dht, "Name");
我认为不需要其他代码,因为它是默认的INotifyPropertyChanged实现,唯一的区别是我向模型传递了一个Action(control.Invoke),以在主线程上调用更新。
问候

xzabzqsa

xzabzqsa1#

我有同样的问题,解决添加一个由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));           
    }
rggaifut

rggaifut2#

我注意到了.NET和Mono之间的区别,我也遇到了同样的问题。在比较了.NET和Mono源代码之后,首先出现的是,如果你想在ViewForm中接收到一个propertyName通知,那么你首先必须在你的模型中:

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 ();
        }
    }
}

这看起来代码很多,但我仍然在寻找一个优雅的甚至更好的解决方案。

rbl8hiat

rbl8hiat3#

他们在这种情况下有什么新的经验吗?我开始了一个新的项目,为树莓开发一个远程应用程序(RS232,GUI和HTTP Act/Response),并且不会改变我的编程语言- C#。我在一些我意想不到的地方得到了很多快速目标-串行和GPIO可以很好地与VS 2022编写的代码一起工作-但我不期望在这一点上出现停止标志。在INotifyPropertyChanged事件触发后,按钮上的简单文本不会更新。与此处描述的完全相同。我发现,在主代码中可以识别该事件。我向ViewModel事件订阅了一个委托,该委托被调用。

viewModel.PropertyChanged += UpdateLabel;

A solved initial problem (beginners failure) with the complete small code is here

相关问题