C# - .Net4.0, Visual Studio 2010C# пользовательский элемент управления - Перерисовка после изменения свойств объекта-члена
По некоторым причинам я использую отдельный класс для хранения некоторых свойств моего пользовательского элемента управления (свойства, чтобы сделать с рисованием сетки). Это вызывает некоторые проблемы, так как я хотел бы иметь возможность вызывать «Invalidate()» в любое время, когда эти значения редактируются (либо через окно свойств, либо во время выполнения), чтобы автоматически перерисовывать элемент управления. Лучшее решение, которое я мог придумать, это реализовать INotifyPropertyChanged в моем классе «GridProperties», отключить событие PropertyChanged в любое время, когда вызываются соответствующие «set» accessors, а затем подписаться на обработчик события PropertyChanged из моего класса управления, чтобы вызвать « Redraw "(который просто вызывает Invalidate()).
Вот укороченная версия моего кода.
class MyControl : Control
{
[Browsable(true)]
public GridProperties Grid { get; set; }
public MyControl()
{
Grid = new GridValues();
Grid.Columns = 4;
Grid.Rows = 4;
Grid.ShowGridLines = true;
Grid.PropertyChanged += Redraw;
}
private void Redraw (object sender, PropertyChangedEventArgs e)
{
Invalidate();
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
//draw gridlines
//draw columns/ rows
}
}
class GridProperties : INotifyPropertyChanged
{
private int columns;
private int rows;
private bool showGridLines;
public int Columns
{
get { return columns; }
set
{
if (columns != value)
{
columns = value;
NotifyPropertyChanged("Columns");
}
}
}
public int Rows...
//same kinda deal for rows & showGridLines
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(string info)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(info));
}
}
Что я ожидал: Redraw вызывается в любое время Grid.Columns/Grid.Rows/Grid.ShowGridLines значения изменяются в любом случае (надеюсь, через окно свойств тоже).
Что происходит: не перерисовывать никогда не вызывается, если я не делаю что-то вроде этого, в совершенно новом методе в MyControl:
Grid.PropertyChanged += Redraw;
Grid.ShowGridLines = false;
Это работает во время выполнения, но это побеждает точку, используя событие менеджером, так как я могу просто установить значения, а затем вызвать Invalidate каждый раз, и это не поможет с любыми изменениями, внесенными в окно свойств.
Если бы кто-нибудь мог дать мне понять, что я делаю неправильно, или есть лучший способ, я бы очень признателен. Честно говоря, я даже не уверен, что подписка на управляющий событиями участника - хорошая практика или нет.
Хм, может быть, ваше свойство Grid заменяется? Если свойство должно быть разрешено полностью воссоздать, а затем на вашем сеттере, вы должны подключиться к событию PropertyChanged (также отцепите предыдущий экземпляр GridProperties), иначе удалите setter для проблем aviod (вы можете использовать инициализаторы свойств для C# 6.0 или private seters для предыдущих версий). – Gusman
Я предполагаю, что ты прав; Я сделал то, что вы рекомендовали, и подключил событие PropertyChanged из сеттера Set Grid, и теперь он работает отлично. Было странно, потому что я не думал, что я явно заменяю Grid (кроме встроенного конструктора MyControl для его инициализации), но в любом случае рад, что он работает сейчас! Благодарю. – 9bjames
Рад, что он работает. Очень возможно, что дизайнер заменяет ваш GridProperties, вы можете проверить файл .designer.cs, должно быть задание. – Gusman