Laden...

Hilfetext anzeigen über AttachedProperty

Erstellt von lutzeslife vor 8 Jahren Letzter Beitrag vor 8 Jahren 3.477 Views
L
lutzeslife Themenstarter:in
155 Beiträge seit 2012
vor 8 Jahren
Hilfetext anzeigen über AttachedProperty

Hallo Community,

ich baue im Moment an einer eigenen WindowKlasse. Überlege ich mir wie ich den Hilfetext zu einem Element anzeigen lassen. Mir geht es darum, dass wenn der Nutzer mit der Mouse über ein bestimmtes Element fährt dass er dann rechts den entsprechenden Text angezeigt bekommt. Das funktioniert auch alles, würde aber gern wissen, was ihr von der Lösung haltet. Ich mache das wie folgt.



public class BaseWindow : Window
{

 public bool AttachMouseMove
        {
            get { return (bool)GetValue(AttachMouseMoveProperty); }
            set { SetValue(AttachMouseMoveProperty, value); }
        }

        public static readonly DependencyProperty AttachMouseMoveProperty =
            DependencyProperty.Register("AttachMouseMove", typeof(bool), typeof(BaseWindow ), new PropertyMetadata(false));

public static bool GetAttachMouseMoveEvent(DependencyObject obj)
        {
            return (bool)obj.GetValue(AttachMouseMoveEventProperty);
        }

        public static void SetAttachMouseMoveEvent(DependencyObject obj, bool value)
        {
            obj.SetValue(AttachMouseMoveEventProperty, value);
        }

        public static readonly DependencyProperty AttachMouseMoveEventProperty =
            DependencyProperty.RegisterAttached("AttachMouseMoveEvent", typeof(bool), typeof(BaseWindow ), new PropertyMetadata(AttachMouseMoveEventPropertyChanged));

        public static void AttachMouseMoveEventPropertyChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
        {
            var frameWorkElement = o as FrameworkElement;

            if (frameWorkElement != null)
            {
                var window = GetWindow(o) as BaseWindow ;

                if (window != null)
                {
                    if ((e.NewValue as bool?).GetValueOrDefault(false))
                    {
                        frameWorkElement.MouseMove += (sender, eee) => { window.ShowHelpTextForControl(sender); eee.Handled = true; };
                    }
                    else
                    {
                        frameWorkElement.MouseMove -= (sender, eee) => { window.ShowHelpTextForControl(sender); eee.Handled = true; };
                    }
                }
            }
        }

}




 <Label Content="df" local:BaseWindow.AttachMouseMoveEvent="{Binding AttachMouseMove}" Tag="TextLabel" Background="Red" HorizontalAlignment="Center" VerticalAlignment="Center"/>


Ich habe also ein AttachedProperty das ich an jedes Element hängen kann. Die bool Variable setze ich im Loaded Event des WIndow (in der BaseWindow Klasse) auf true und im Closed Event auf false, das die Events wieder ababonniert werden.

Natürlich kann ich das auch alles im CodeBehind des jeweiligen Windows das von BaseWindow erbt mit MouseMoveHandler.

So einen richtigen Vorteil hat es nicht, aber sieht nett aus XD Ne im Ernst würde mich über Feedback freuen.

Mit freundlichen Grüßen
lutzeslife

5.299 Beiträge seit 2008
vor 8 Jahren

ich kann nix zu sagen, weil ich kanns nicht nachbauen.
vlt. magstes in die Snippets einstellen - da kann ichs dann runterladen, rumprobieren, und mein Senf zu geben?

Der frühe Apfel fängt den Wurm.

L
lutzeslife Themenstarter:in
155 Beiträge seit 2012
vor 8 Jahren

Ich habe mal ein kleines Projekt gebaut dafür (siehe Anhang) Eine Überlegung war, es an ein Command zu binden, dann wäre es allerdings das gleich wie die Interaktivity Geschichte (EventToCommand) aus Blend.

Mit freundlichen Grüßen
lutzeslife

5.299 Beiträge seit 2008
vor 8 Jahren

och - ich finds ganz ok.

Ich hätt vmtl. das RoutedEvent des Windows behandelt, und wäre da beim MouseMove immer den VisualTree hochgelaufen oder sowas.

Und ich hätte es eher Daten-Orientiert gemacht, also dass ich nicht Controls überwache, sondern letztlich, ob der User mitte Maus über einem meiner Viewmodel-Präsentationen steht.

Aber ist bischen anderer Use-Case.

Der frühe Apfel fängt den Wurm.

L
lutzeslife Themenstarter:in
155 Beiträge seit 2012
vor 8 Jahren

Hey Erfinder des Rats,

ich habe nochmal eine Variante 2 mir Überlegt. Ist noch ohne Fehlerbehandlung und so weiter.


local:EventListener.Attach="MouseMove"

Es wird nur noch deklariert welches Event man will und vorher muss man nur noch entweder im Xaml oder halt per Code die Liste füllen


<local:Events x:Key="attachedMethods">
            <local:EventEntry EventName="MouseMove" CalledMethod="Test"/>
        </local:Events>


local:EventListener.BindedEvents="{StaticResource attachedMethods}"

Der Rest wird über Reflection gemacht.

Über Feedback wäre ich dankbar, vielleicht kann man das auch noch ein wenig ausbauen.

Mit freundlichen Grüßen
lutzeslife

5.299 Beiträge seit 2008
vor 8 Jahren

Hi!

Ich bin noch bisserl am gucken, ich muss auch bischen umbauen, weil ich nur VS2013 hab.

Was mir auffält ist ein bischen glaub kritischer Umgang mit null-Werten - Beispiel:


      static void AttachCallback(DependencyObject o, DependencyPropertyChangedEventArgs e)        {
            var eventName = e.NewValue as string;
            if (string.IsNullOrEmpty(eventName)) return;
            if (AttachedEvents == null || string.IsNullOrEmpty(AttachedEvents[eventName])) return;
            var eventInfo = o?.GetType().GetEvent(eventName);
            var eventType = eventInfo?.EventHandlerType;
            var window = Window.GetWindow(o);
            var method = window.GetType().GetMethod(AttachedEvents[eventName]);
            var handler = Delegate.CreateDelegate(eventType, window, method);
            eventInfo.AddEventHandler(o, handler);
        }

Aus Zeile #5 kann das EventInfo als null hervorgehen, etwa wenn ein unsinniger EventName angegeben ist (glaubich jds, müsste man testen, oder Doku lesen).
Imo sollte man da eine Exception werfen, aber bei dir wird das laufengelassen, bis schließlich ein handler createt wird, bei dem sowohl eventType als auch method nichts rechtes sein können.

Wie gesagt: Wenn da ein ungültiger EventName gegeben ist, wird das komisch.
Hingegen den Test, ob o null ist, kannste dir sparen: o kann nicht null sein, denn an null kann nichts attached werden.

So insgesamt habich den Eindruck, das ganze macht ungefähr dasselbe, was auch ein Tooltip machen täte, also ich will jetzt nicht, sagen, dass du da vlt. das Rad neu erfindest, aber ich sags trotzdem :evil:

Was mir noch fehlt ist, dass der Text auch wieder verschwindet, wenn man vom Control runter ist.

Der Vorzug der 2. Variante ist mir auch nicht ganz klar, ich mag die erste lieber, sind ein paar Zeilen weniger.

Der frühe Apfel fängt den Wurm.