Как связать значение свойства/поля класса с свойством контрола?
Я хочу поместить ссылку на строку в класс
public class MyClass {
public ref string Value; //компилятор говорит, что так нельзя
//...
}
чтобы сделать так:
MyClass foo = new();
foo.Value = ref SomeTextbox.Text;
SomeTextbox.Text = "something" //допустим, пользователь что-то вводит
MessageBox.Show(foo.Value) //"something"
В моём случае, области видимости (и, соответственно, время жизни) текстбокса и моего класса одинаковы. Поэтому, хотелось бы задать Value в качестве ссылки на текстбокс. Можно ли это сделать?
Я знаю об альтернативных решениях с использованием:
- Обработчиков событий
TextChangedилиLostFocus Tag
но мне просто интересна сама возможность использования ссылки внутри класса, как правильно её внутри класса объявлять и как назначать. И если поле другого класса совсем невозможно использовать в качестве ссылки, то вопрос всё равно актуален – как тогда поместить ссылку на TextBox.. или вообще любую другую (текстбокс здесь для примера) внутрь динамического класса?
Например foo.Value = ref SomeExampleString – как я должен объявить Value в классе, чтобы это работало?
Ответы (1 шт):
Через ref не получится, так как свойство контрола не является полем. Получится через привязку данных.
Сначала надо реализовать интерфейс INotifyPropertyChanged, например в базовом классе.
public class NotifyPropertyChanged : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
Теперь код вашего класса изменить вот так
public class MyClass : NotifyPropertyChanged
{
private string value;
public string Value
{
get => value;
set
{
this.value = value;
OnPropertyChanged();
}
}
}
Создам форму, на которой будет Label и Button. Назначу 2 обработчика Form1.Load и Button.Click, получится вот такой код.
public partial class Form1 : Form
{
private MyClass data;
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
data.Value = DateTime.Now.ToString();
}
private void Form1_Load(object sender, EventArgs e)
{
data = new MyClass();
label1.DataBindings.Add(nameof(Label.Text), data, nameof(MyClass.Value));
// эквивалент label1.DataBindings.Add("Text", data, "Value");
}
}
Теперь при изменении свойства Value у класса, текст в метке изменится автоматически.
При этом не следует напрямую обращаться к label1.Text и не следует обращаться к полю value у класса с данными вне геттера и сеттера свойства Value. То есть из кода можно обращаться только к свойству MyClass.Value, тогда все привязанные к нему контролы будут своевременно обновляться.
Более сложные случаи привязок для Winforms я рассматривал здесь.
