简体   繁体   English

C#中的数据绑定问题

[英]Problem with data binding in C#

I'm trying to understand better how data binding works in .net. 我试图更好地理解数据绑定在.net中的工作原理。 I was checking this article, and I came up with this code: 我正在查看这篇文章,我想出了这段代码:

public partial class Form1 : Form//, INotifyPropertyChanged
{
    public event PropertyChangedEventHandler MyTextChanged;

    [System.ComponentModel.Bindable(true)]
    public string MyText
    {
        get { return textBox1.Text; }
        set 
        {
            textBox1.Text = value;
            if (MyTextChanged != null)
                MyTextChanged(this, new PropertyChangedEventArgs("MyText"));
        }
    }

    MyClass myClass { get; set; }

    public Form1()
    {
        InitializeComponent();
        myClass = new MyClass();
        Binding binding = new Binding("MyText", myClass, "Dic");
        binding.Parse += new ConvertEventHandler(binding_Parse);
        binding.Format += new ConvertEventHandler(binding_Format);
        DataBindings.Add(binding);
        myClass.AddStuff("uno", "UNO");
    }

    void OnMyTextChanged(PropertyChangedEventArgs e)
    {
        if (MyTextChanged != null) MyTextChanged(this, e);
    }

    void binding_Format(object sender, ConvertEventArgs e)
    {
        if (e.Value is Dictionary<string, string>)
        {
            Dictionary<string, string> source = (Dictionary<string, string>)e.Value;
            e.Value = source.Count.ToString();
        }
    }

    void binding_Parse(object sender, ConvertEventArgs e)
    {
        MessageBox.Show(e.DesiredType.ToString());
    }

    private void changemyClassButton_Click(object sender, EventArgs e)
    {
        myClass.AddStuff(myClass.Dic.Count.ToString(), "'" + myClass.Dic.Count.ToString() + "'");
    }

    private void changeMyTextButton_Click(object sender, EventArgs e)
    {
        MyText = "1234";
    }
}

public class MyClass : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    public Dictionary<string, string> Dic { get; set; }

    public MyClass()
    {
        Dic = new Dictionary<string, string>();
    }

    public void AddStuff(string key, string value)
    {
        Dic.Add(key, value);
        if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs("Dic"));
    }
}

I'm trying to bind MyText to myClass . 我正在尝试将MyText绑定到myClass The problem is that the function binding_Parse is never being called. 问题是从不调用函数binding_Parse I know I could probably bind textBox1.Text directly to myClass , or that there might be a thousand other possible ways to do what I'm trying to do, but this is just a practice; 我知道我可以将textBox1.Text直接绑定到myClass ,或者可能有其他一千种方法可以做我正在尝试做的事情,但这只是一种练习; I'm trying to understand better data binding. 我正在尝试理解更好的数据绑定。 So I want to bind a custom object to a custom property so I can see the process from end to end. 所以我想将自定义对象绑定到自定义属性,以便我可以从头到尾看到该过程。 The custom object is myClass , and the custom property is MyText . 自定义对象是myClass ,自定义属性是MyText I've tried all kinds of variations, like implementing INotifyPropertyChanged , but I can't get binding_Parse to be called (I would expect it to be called when I call changeMyTextButton_Click ). 我已经尝试了各种变体,比如实现INotifyPropertyChanged ,但是我无法调用binding_Parse (我希望在调用changeMyTextButton_Click时调用changeMyTextButton_Click )。 Am I missing something? 我错过了什么吗?

Edit: To put it simpler: I want to write a user control with a property string MyText that then a user can bind to something else, the same way you can bind a TextBox 's Text property to something else. 编辑:更简单:我想编写一个带有属性string MyText的用户控件,然后用户可以绑定到其他东西,就像将TextBoxText属性绑定到其他东西一样。 So I don't want to bind to the property of a control to an object, I want to write a control with a property that then a user can bind to an object. 所以我不想将控件的属性绑定到对象,我想用一个属性编写一个控件,然后用户可以绑定到一个对象。

OK I figured it out in case anyone had the same problem. 好吧我想出来以防万一有人遇到同样的问题。 I had to create an event handler named MyTextChanged to let the Binding knows MyText is changing, and set the Binding s DataSourceUpdateMode property to OnPropertyChanged . 我必须创建一个名为MyTextChanged的事件处理程序,让Binding知道MyText正在改变,并将BindingDataSourceUpdateMode属性设置为OnPropertyChanged Using this simple principle I can bind a pixel in my screen to the rest of the universe :). 使用这个简单的原理,我可以将屏幕上的像素绑定到宇宙的其余部分:)。 Here's the code: 这是代码:

public partial class Form1 : Form
{
    public event EventHandler MyTextChanged;

    [Bindable(true)]
    public string MyText
    {
        get { return textBox1.Text; }
        set 
        {
            if (textBox1.Text != value)
            {
                textBox1.Text = value;
                OnMyTextChanged();
            }
        }
    }

    MyClass myClass { get; set; }

    public Form1()
    {
        InitializeComponent();
        myClass = new MyClass();
        Binding binding = new Binding("MyText", myClass, "Dic");
        binding.DataSourceUpdateMode = DataSourceUpdateMode.OnPropertyChanged;
        binding.Parse += new ConvertEventHandler(binding_Parse);
        binding.Format += new ConvertEventHandler(binding_Format);
        DataBindings.Add(binding);
        myClass.AddStuff("uno", "UNO");
    }

    void OnMyTextChanged()
    {
        if (MyTextChanged != null) MyTextChanged(this, EventArgs.Empty);
    }

    void binding_Format(object sender, ConvertEventArgs e)
    {
        if (e.Value is Dictionary<string, string>)
        {
            Dictionary<string, string> source = (Dictionary<string, string>)e.Value;
            e.Value = source.Count.ToString();
        }
    }

    void binding_Parse(object sender, ConvertEventArgs e)
    {
        MessageBox.Show(e.DesiredType.ToString());

    }

    private void changemyClassButton_Click(object sender, EventArgs e)
    {
        myClass.AddStuff(myClass.Dic.Count.ToString(), "'" + myClass.Dic.Count.ToString() + "'");
    }

    private void changeMyTextButton_Click(object sender, EventArgs e)
    {
        MyText = "1234";
    }
}

public class MyClass : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    public Dictionary<string, string> Dic { get; set; }

    public MyClass()
    {
        Dic = new Dictionary<string, string>();
    }

    public void AddStuff(string key, string value)
    {
        Dic.Add(key, value);
        if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs("Dic"));
    }
}

Perhaps this will help you out, understanding when Parse event is executed. 也许这会帮助你理解何时执行Parse事件。

To see binding_Parse working check out this sample: 要查看binding_Parse工作,请查看此示例:

public partial class Form1 : Form
{

    public MyClass myClass { get; set; }

    public Form1()
    {
        InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e)
    {
        myClass = new MyClass();
        myClass.AddStuff("uno", "UNO");

        Binding b = new Binding("Text", myClass, "Dic");
        b.Parse += new ConvertEventHandler(b_Parse);
        b.Format += new ConvertEventHandler(b_Format);
        textBox1.DataBindings.Add(b);
    }

    void b_Format(object sender, ConvertEventArgs e)
    {
        e.Value = (e.Value as Dictionary<string, string>)["uno"].ToString();
        textBox1.Text = e.Value.ToString();
    }

    void b_Parse(object sender, ConvertEventArgs e)
    {
        MessageBox.Show("This is executed when you lost focus\n\nI'm parsing your entered text: " + e.Value);
    }


}

You just have debug. 你只需要调试。 Click on the button, and notice Format event is called first. 单击按钮,然后注意首先调用Format事件。 Then if you manually change textbox1.Text value, when you click on the button again, there will be a lost focus, and then Parse event will be executed. 然后,如果您手动更改textbox1.Text值,当您再次单击该按钮时,将会失去焦点,然后将执行Parse事件。

To create your custom control also check this site . 要创建自定义控件,请检查此站点

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM