Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 | Suche | FAQ

Hauptmenü
myCSharp.de
» Startseite
» Forum
» Suche
» Regeln
» Wie poste ich richtig?

Mitglieder
» Liste / Suche
» Wer ist online?

Ressourcen
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Microsoft Docs

Team
» Kontakt
» Cookies
» Spenden
» Datenschutz
» Impressum

  • »
  • Community
  • |
  • Diskussionsforum
Attached Propertiesmithilfe generischer Basisklasse in einer Zeile erzeugen
CoderboyPB
myCSharp.de - Member



Dabei seit:
Beiträge: 291
Herkunft: Paderborn

Themenstarter:

Attached Propertiesmithilfe generischer Basisklasse in einer Zeile erzeugen

beantworten | zitieren | melden

Nachfolgenden Code habe ich aus diesem Video (bzw. dem zugehörigen GitHub Repository):https://www.youtube.com/watch?v=trR5RQGEteM

Die Idee dahinter ist, Att. Prop. mit einer Zeile erzeugen zu können:

z.B.


public class SecurityIdProperty : BaseAttachedProperty<SecurityIdProperty, string> { }

Angewendet werden soll das dann z.B. so:

<TextBox local:SecurityIdProperty.Value="123" ... />

Jetzt aber kommt das, was ich nicht verstehe: Zum einen kennt XAML SecurityIdProperty nicht, statt dessen aber bietet mir die 'Intelligence' local:BaseAttachedProperty`2 an.

Vor allem das `2 lässt mich neugierig zurück ...

Das ganze ist ja nicht meine Idee, der Programmierer im Video macht es aber genau so ...

Irgendjemand ne Idee, was mir VS da sagen möchte?


public abstract class BaseAttachedProperty<Parent, Property>
        where Parent : BaseAttachedProperty<Parent, Property>, new()
    {
        #region Public Events

        /// <summary>
        /// Fired when the value changes
        /// </summary>
        public event Action<DependencyObject, DependencyPropertyChangedEventArgs> ValueChanged = (sender, e) => { };

        #endregion

        #region Public Properties

        /// <summary>
        /// A singleton instance of our parent class
        /// </summary>
        public static Parent Instance { get; private set; } = new Parent();

        #endregion

        #region Attached Property Definitions

        /// <summary>
        /// The attached property for this class
        /// </summary>
        public static readonly DependencyProperty ValueProperty = DependencyProperty.RegisterAttached("Value", typeof(Property), typeof(BaseAttachedProperty<Parent, Property>), new UIPropertyMetadata(new PropertyChangedCallback(OnValuePropertyChanged)));

        /// <summary>
        /// The callback event when the <see cref="ValueProperty"/> is changed
        /// </summary>
        /// <param name="d">The UI element that had it's property changed</param>
        /// <param name="e">The arguments for the event</param>
        private static void OnValuePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            // Call the parent function
            Instance.OnValueChanged(d, e);

            // Call event listeners
            Instance.ValueChanged(d, e);
        }

        /// <summary>
        /// Gets the attached property
        /// </summary>
        /// <param name="d">The element to get the property from</param>
        /// <returns></returns>
        public static Property GetValue(DependencyObject d) => (Property)d.GetValue(ValueProperty);

        /// <summary>
        /// Sets the attached property
        /// </summary>
        /// <param name="d">The element to get the property from</param>
        /// <param name="value">The value to set the property to</param>
        public static void SetValue(DependencyObject d, Property value) => d.SetValue(ValueProperty, value);

        #endregion

        #region Event Methods

        /// <summary>
        /// The method that is called when any attached property of this type is changed
        /// </summary>
        /// <param name="sender">The UI element that this property was changed for</param>
        /// <param name="e">The arguments for this event</param>
        public virtual void OnValueChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e) { }

        #endregion
    }
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von CoderboyPB am .
private Nachricht | Beiträge des Benutzers
Th69
myCSharp.de - Experte

Avatar #avatar-2578.jpg


Dabei seit:
Beiträge: 3984

beantworten | zitieren | melden

Hast du denn in der XAML-Datei für local den passenden Namespace eingetragen?

BaseAttachedProperty`2 ist die interne Bezeichnung, das dies eine generische Klasse ist (` ist das Trennzeichen, da es nicht für .NET-Namen verwendent werden darf - und die Zahl dahinter ist die Anzahl der Parameter), s.a. What's the meaning of “apostrophe + number” in the object type of properties with generics (eg. “Collection`1”)?
private Nachricht | Beiträge des Benutzers
CoderboyPB
myCSharp.de - Member



Dabei seit:
Beiträge: 291
Herkunft: Paderborn

Themenstarter:

beantworten | zitieren | melden

ja, der Namespace ist selbstverständlich eingetragen.
Das ist ja das Unverständliche.
private Nachricht | Beiträge des Benutzers
CoderboyPB
myCSharp.de - Member



Dabei seit:
Beiträge: 291
Herkunft: Paderborn

Themenstarter:

beantworten | zitieren | melden

Komischerweise taucht der Namespace in der Liste beim setzen mit xmlns: doppelt in der Liste auf, wenn ich den zweiten wähle klappt es, beim ersten nicht. Ziemlich komisch. Scheint echt ein Fehler von VS zu sein.
private Nachricht | Beiträge des Benutzers
p!lle
myCSharp.de - Member

Avatar #avatar-3556.jpg


Dabei seit:
Beiträge: 1053

beantworten | zitieren | melden

Zitat von CoderboyPB
Komischerweise taucht der Namespace in der Liste beim setzen mit xmlns: doppelt in der Liste auf, wenn ich den zweiten wähle klappt es, beim ersten nicht. Ziemlich komisch. Scheint echt ein Fehler von VS zu sein.

Hä?
Kannst du mal bitte den XAML-Code zeigen?
private Nachricht | Beiträge des Benutzers
CoderboyPB
myCSharp.de - Member



Dabei seit:
Beiträge: 291
Herkunft: Paderborn

Themenstarter:

beantworten | zitieren | melden

Zur Erklärung: der Code enthält ein Window Chrome, und das überschriebene Template der TextBox stammt aus einem anderen Beispiel, ich habe die jetzt drinnen gelassen, um den Code wirklich hier 1:1 wieder zu geben.

<Window x:Class="Facetto.Word.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:my="clr-namespace:Fasetto.Word"
        mc:Ignorable="d"
        AllowsTransparency="True"
        WindowStyle="None"
        Title="MainWindow" Height="450" Width="800">
    <WindowChrome.WindowChrome>
        <WindowChrome
            GlassFrameThickness="0"
            ResizeBorderThickness="4"
            CaptionHeight="36"
            />
    </WindowChrome.WindowChrome>
    <Window.Template>
        <ControlTemplate TargetType="Window">
            <Grid>
                <Border Padding="10"
                        Background="Blue"
                        CornerRadius="30"
                        x:Name="border"
                        >
                </Border>
                <ContentPresenter>
                    <ContentPresenter.OpacityMask>
                        <VisualBrush Visual="{Binding ElementName=border}"/>
                    </ContentPresenter.OpacityMask>
                </ContentPresenter>
            </Grid>
        </ControlTemplate>
    </Window.Template>
    <Grid>
        <TextBox Text="foooooo" Width="200" Height="50"
                 my:SecurityIdProperty.Value="123"
                 >
            
            <TextBox.Template>
                <ControlTemplate TargetType="TextBox">
                    <Grid Background="White">
                        <TextBox Text="{TemplateBinding Text}" FontSize="30"/>
                        <TextBlock 
                            Text ="{TemplateBinding my:SecurityIdProperty.Value}"
                            VerticalAlignment="Bottom"
                            HorizontalAlignment="Right"/>
                    </Grid>
                </ControlTemplate>
            </TextBox.Template>
        </TextBox>

    </Grid>
</Window>

Und hier der Screenshot mit dem doppelten Namespace:
Bild entfernt - Coffeebean [Hinweis] Wie poste ich richtig?, Punkt 6.1: Bilder als Dateianhang hochladen
private Nachricht | Beiträge des Benutzers
MrSparkle
myCSharp.de - Team

Avatar #avatar-2159.gif


Dabei seit:
Beiträge: 5961
Herkunft: Leipzig

beantworten | zitieren | melden

Der Namespace ist einmal als "Facetto" und einmal als "Fasetto" geschrieben. Schreibst du das alles mit der Hand?
Weeks of programming can save you hours of planning
private Nachricht | Beiträge des Benutzers
CoderboyPB
myCSharp.de - Member



Dabei seit:
Beiträge: 291
Herkunft: Paderborn

Themenstarter:

beantworten | zitieren | melden

xaml ja, die BaseAttachedProperty nicht

Aber es lag wohl tatsächlich an den Namespaces, aber beide Namespaces existierten ja. Bissel komisch.
Hauptsache es geht jetzt.

Jetzt geht es an den nächsten Schritt: Den Teil mit den Events verstehen. Kann zwar Events, aber dieses rekursive generische macht es etwas komplizierter :)
private Nachricht | Beiträge des Benutzers
MrSparkle
myCSharp.de - Team

Avatar #avatar-2159.gif


Dabei seit:
Beiträge: 5961
Herkunft: Leipzig

beantworten | zitieren | melden

Ich kann mir ehrlich gesagt keinen Anwendungsfall vorstellen, wo so etwas benötigt wird. Kannst du mal beschreiben, was du eigentlich vor hast?
Weeks of programming can save you hours of planning
private Nachricht | Beiträge des Benutzers
CoderboyPB
myCSharp.de - Member



Dabei seit:
Beiträge: 291
Herkunft: Paderborn

Themenstarter:

beantworten | zitieren | melden

Lernen, Lernen, Lernen ...
Praktische Gehversuche:

Am Anfang ein eigenes überschriebenes Window Chrome

Das Beispiel der überschriebenen TextBox stammt aus diesem Artikel als Beispiel für die Verwendung einer Attached Property:https://www.codemag.com/article/1405061

Und aus dem bereits genannten YT Video stammt die BaseAttachedProperty, mit welcher ich dann die normale A-Propperty ersetzt habe.

Nen Sinn steckt da tatsächlich nicht hinter. Außer wie gesagt halt, der Lernprozess, denn ich möchte jeden Tag etwas besser werden. Das ist mein Ziel.

Und das Hauptziel ist, ich will wieder arbeiten, leider ist es schwer mit meinen gesundheitlichen Einschränkungen, aber ich denke ich habe gute Chancen bei meinem Ex Arbeitgeber auf Minijob Basis unterzukommen.
private Nachricht | Beiträge des Benutzers
MrSparkle
myCSharp.de - Team

Avatar #avatar-2159.gif


Dabei seit:
Beiträge: 5961
Herkunft: Leipzig

beantworten | zitieren | melden

Ich glaube, du verrennst dich da in etwas. Das alles hat keinerlei praktische Relevanz. Lerne doch lieber Sachen, die man auch anwenden kann. Erfahrung mit MVVM bpsw. kann man in jedem WPF-Projekt gebrauchen.
Weeks of programming can save you hours of planning
private Nachricht | Beiträge des Benutzers
CoderboyPB
myCSharp.de - Member



Dabei seit:
Beiträge: 291
Herkunft: Paderborn

Themenstarter:

beantworten | zitieren | melden

MVVM habe ich inzwischen komplett verstanden, bin dabei auch auf Caliburn.Micro gestoßen, hatte mich überzeugt
private Nachricht | Beiträge des Benutzers
MrSparkle
myCSharp.de - Team

Avatar #avatar-2159.gif


Dabei seit:
Beiträge: 5961
Herkunft: Leipzig

beantworten | zitieren | melden

Das ist nicht was ich meinte. Wenn du weißt, wie ein Klavier funktioniert, dann heißt das noch lange nicht, daß du es auch spielen kannst.

Versuch doch einfach mal, ein komplettes Projekt umzusetzen. Sowas wie eine einfache Todo-Liste oder ein Spiel wie MineSweeper. Das würde dir eine Menge praktischer Erfahrung einbringen. Das kannst du alles mit WPF und MVVM umsetzen, und alle Funktionien mit Unit-Tests abdecken. Mit einem solchen Projekt kannst du dich dann für einen Job bewerben.

Ich arbeite mit WPF seitdem es das gibt, und habe Anwendungen aus den unterschiedlichsten Bereichen damit umgesetzt. Und ich habe dafür nie ein Windows Chrome oder ein Attached Property erstellen müssen. Und wenn man es doch mal benötigt, kann man nachschauen, wie es geht. Viel wichtiger ist die Erfahrung, die man nur mit richtigen Projekten sammeln kann.
Weeks of programming can save you hours of planning
private Nachricht | Beiträge des Benutzers
dorogz
myCSharp.de - Member



Dabei seit:
Beiträge: 1

beantworten | zitieren | melden

Könnten Sie mir bitte sagen, wie Sie dieses Problem gelöst haben. Ich sitze schon lange an diesem Problem und habe keine Lösung gefunden. Wie bekomme ich Intellisense dazu, die benutzerdefinierten angehängten attached properties? Meine Anwendung wirft einen Fehler, der besagt:
Fehler
... the method or operation is not implemented.

Das Bild Ihrer Lösung, die ich glaube, Sie hier hinzugefügt ist nicht mehr verfügbar ...
Thanks!

private Nachricht | Beiträge des Benutzers
CoderboyPB
myCSharp.de - Member



Dabei seit:
Beiträge: 291
Herkunft: Paderborn

Themenstarter:

beantworten | zitieren | melden

Habe dorogz via PM geholfen.

Falls sich mal wieder jemand hier hin verirrt: Habe es eben gerade, nachdem ich das Projekt wieder neu gemacht hatte mit einem 'Projektmappe neu erstellen' sehr schnell lösen können.
private Nachricht | Beiträge des Benutzers
FZelle
myCSharp.de - Experte



Dabei seit:
Beiträge: 10068

beantworten | zitieren | melden

Bitte keine antworten per PM.
Du hast bestimmt auch schon antworten einfach hier gefunden, so klappt das aber nicht.
private Nachricht | Beiträge des Benutzers