2016-05-03 6 views
0

C# zu ändern - .Net4.0, Visual Studio 2010C# benutzerdefinierte Steuerung - Redraw nach einem Mitglied Eigenschaften des Objekts

Aus bestimmten Gründen ich eine eigene Klasse bin mit den Eigenschaften einige meiner benutzerdefinierten Steuerelement zu speichern (Eigenschaften zu tun mit dem Zeichnen eines Gitters). Dies verursacht einige Probleme, da ich gerne "Invalidate()" jedes Mal aufrufen könnte, wenn diese Werte bearbeitet werden (entweder über das Eigenschaftenfenster oder während der Laufzeit), um das Steuerelement automatisch neu zu zeichnen. Die beste Lösung, die ich mir vorstellen konnte, war die Implementierung von INotifyPropertyChanged innerhalb meiner "GridProperties" -Klasse, das Auslösen eines PropertyChanged-Ereignisses zu jedem Zeitpunkt des Aufrufs der entsprechenden "set" -Accessoren und das anschließende Abonnieren des PropertyChanged-Ereignishandlers aus meiner Steuerelementklasse. Redraw "-Methode (die gerade Invalidate() aufruft).

Hier ist eine verkürzte Version meines Codes bisher.

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

Was ich erwartet hatte: Redraw jederzeit Grid.Columns/Grid.Rows/Grid.ShowGridLines Werte in irgendeiner Weise (auch hoffentlich durch Eigenschaften Fenster) geändert werden, aufgerufen wird.

Was geschieht: ReDraw wird nie genannt, es sei denn ich etwas tun, in einer völlig neuen Methode in MyControl:

Grid.PropertyChanged += Redraw; 
Grid.ShowGridLines = false; 

Dies funktioniert während der Laufzeit, aber diese Niederlagen der Punkt ein Ereignis der Verwendung von Manager, da ich nur die Werte festlegen und dann Invalidate jedes Mal aufrufen kann, und es hilft nicht mit Änderungen, die über das Eigenschaftsfenster vorgenommen werden.

Wenn jemand mir einen Hinweis geben könnte, was ich falsch mache oder ob es einen besseren Weg gibt, würde ich es wirklich schätzen. Ganz ehrlich, ich bin mir nicht einmal sicher, ob das Abonnieren eines Event-Managers eines Mitglieds gute Praxis ist oder nicht.

+0

Hmmm, vielleicht wird Ihre Grid-Eigenschaft ersetzt? Wenn die Eigenschaft vollständig neu erstellt werden soll, müssen Sie sie beim PropertyChanged-Ereignis haken (entfernen Sie auch die vorherige GridProperties-Instanz), andernfalls entfernen Sie den Setter für aviod-Probleme (Sie können Property-Initialisierer für C# 6.0 oder private Setter verwenden für frühere Versionen). – Gusman

+0

Ich vermute, du hast recht; Ich habe getan, was Sie empfohlen haben und das PropertyChanged-Ereignis von innerhalb des Grid-Setters angeschlossen, und jetzt scheint es perfekt zu funktionieren. Ich fand es merkwürdig, da ich nicht dachte, dass ich Grid explizit ersetzen würde (abgesehen von MyControls Konstruktor, um es zu initialisieren), aber so oder so froh, dass es jetzt funktioniert! Vielen Dank. – 9bjames

+0

Froh, dass es funktioniert. Es ist sehr gut möglich, dass der Designer Ihre GridProperties ersetzt, Sie können die Datei .designer.cs überprüfen, dort sollte die Zuweisung sein. – Gusman

Antwort

1

Danke an Gusman für die Lösung. Statt Einhaken bis zu Property aus MyControl Konstruktor, ich nur, um es von innen Grid Setter angeschlossen, etwa so:

private GridProperties grid; 
[Browsale(true)] 
public GridProperties Grid 
{ 
    get 
    { 
     return grid; 
    } 
    set 
    { 
     if(grid! = null) 
      grid.PropertyChanged -= Redraw; 

     grid = value; 
     grid.PropertyChanged += Redraw; 
    } 
} 

kann ich nur annehmen, das Objekt meiner GridProperties irgendwo etwas zu ersetzen. So oder so, wann immer der Grid-Setter aufgerufen wird Ich hänge den PropertyChanged-Event-Manager einfach ab und hänge ihn erneut an. Jetzt wird der Bildschirm aktualisiert, wenn die Grid-Werte geändert werden, entweder nach Code oder aus dem Eigenschaftenfenster.

Verwandte Themen