Kleine Hilfe – RollNut ~ Blog http://blog.rollnut.com Sun, 11 Apr 2021 07:35:07 +0000 de-DE hourly 1 https://wordpress.org/?v=5.7.11 Git Glossar http://blog.rollnut.com/git-glossar/ Mon, 30 Jan 2017 13:43:20 +0000 http://blog.rollnut.com/?p=748 Hier findet Ihr die wichtigsten Git-Befehle. Selbst wenn Ihr eine grafische Git-Oberfläche verwendet ist es gut zu wissen welche Shell-Befehle es gibt und was diese tun.

Git einrichten
init Neues Repository erstellen (aktuelles Verzeichnis).
init --bare Ein zentrales Repository erstellen.
Achtung! Der Ordnername sollte mit .git enden (z.B. my-project.git).
clone <repo> Kopiert ein Repository welches unter <repo> zu finden ist.
config --global Globale Konfiguration von git (z.B. Benutzerinfo angeben).
Mit Git lokal arbeiten
add <name> Dateien und Ordner zur "Staging Area" hinzufügen (abhängig von <name>).
Mit * werden alle Änderung hinzugefügt (.ignore-Regeln werden aber beachtet).
commit Änderungen in der "Staged Area" werden in das lokale Repository übernommen.
stash Speichert alle lokalen Änderungen in ein lokales Stash-Objekt.
Nützlich um aktuelle Arbeit ohne Commit zu sichern.
status Zeigt offene Änderungen, welche noch nicht committed wuden.
log Zeigt Commits (Ausgabe kann über Parameter eingestellt werden, wie z.B. --graph).
Branching
branch Branches verwalten (erstellen, löschen, umbenennen)
checkout <branch> Von einem Branch in ein anderes wechseln.
Es können auch einzelne Dateien oder Commits ausgecheckt werden.
merge --no-ff <branch> Das aktuelle Branch mit <branch> zusammenführen.
Für Größere merges empfiehlt es sich immer --no-ff zu verwenden (bessere Chronik).
Nach dem Merge muss normal committed werden.
Git synchronisieren (mit zentralem Repository)
remote Remote-Verbindungen verwalten.
Dieser Befehl erstellt quasi ein Alias für umständlich lange URL's.
fetch Git holt sich den aktuellen Stand des zentralen Repositories (ohne merge).
Dies kann nützlich sein um erst ein Review vor dem git merge zu machen.
pull Macht das selbe wie "git fetch" aber zusätzlich noch "git merge".
push Lokale Commits zum zentralen Repository schicken.
Fortgeschrittene Funktionen
checkout Kann ältere Commits wiederherstellen (oder zu einem anderen Branch wechseln).
revert TODO
reset TODO
clean TODO
commit --amend Änderungen dem letzten Commit hinzufügen (nur erlaubt solange noch kein push erfolgt ist!).
rebase TODO
reflog TODO

Tipps & Tricks

Lokale Änderungen verwerfen

Folgende Befehle verwerfen alle Änderungen und stellen quasi den Server-Zustand her:

git reset --hard
git clean -df

Squash - (Lokale) Commits zusammenführen

Manchmal ist es praktisch Zwischenstände in kurzen Abständen zu committen, besonders um etwas auszuprobieren. Blöd nur wenn jedes "Mini"-Commit zum Server geschickt wird. In so einem Fall wünscht man sich eine Merge-Funktion der lokalen Commits um einen großen zu erhalten.

Achtung: Dieser Befehl darf nur für lokale Commits angewendet werden welche noch nicht zum Server gepusht wurden!

Folgt noch...
]]>
Content-Unterstützung via XAML für UserControls http://blog.rollnut.com/content-unterstuetzung-via-xaml-fuer-usercontrols/ Sat, 23 Jan 2016 14:20:48 +0000 http://blog.rollnut.com/?p=162 UserControls sind modulare bzw. fertige (Programm)-Komponenten die nach außen gekapselt sind. Manchmal währe es praktisch beim Verwenden eines UserControls, neben den üblichen Properties, den Inhalt direkt im XAML-Code zu definieren und einzubetten.

Ich habe zur Demonstration ein UserControl erstellt, welches ein Grid mit blauen Hintergrund enthält. In diesem Grid soll der Inhalt gezeigt werden, welcher vom Verwender definiert wird (<ContentPresenter />).

<UserControl 
    x:Class="ContentWPF.MyUserControl"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
>
    <Grid Background="Blue">
        <ContentPresenter />
    </Grid>
</UserControl>

Die Verwendung von dem UserControl wird wie üblich in XAML deklariert mit dem Unterschied das man diesmal direkt im XAML den Content angibt.

<local:MyUserControl>
    Hello World
</local:MyUserControl>

 Das Problem

Nun ist es so das am Ende nichts von der Definition des Controls (‚MyUserControl.xaml‘) gezeigt wird. Es wird nur noch „Hello World“ ohne Grid und ohne Blau dargestellt.

Der Grund ist, dass das Content-Property von UserControl mit dem Content des Verwenders überschrieben wird und dabei die eigentliche Definition verloren geht.

Mit diesem Wissen ist der nächste Schritt nun zu verhindern, dass das Content-Property überschrieben wird. Das machen wir einfach indem wir im CodeBehind von ‚MyUserControl‘ ein separates Content-Property anlegen.

public static readonly DependencyProperty MyContentProperty 
    = DependencyProperty.Register("MyContent", typeof(object), typeof(MyUserControl), null);
public object MyContent
{
    get { return (object)GetValue(MyContentProperty); }
    set { SetValue(MyContentProperty, value); }
}
<UserControl 
    x:Class="ContentWPF.MyUserControl"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
>
    <Grid Background="Blue">
        <ContentPresenter Content="{Binding Path=MyContent,
          RelativeSource={RelativeSource  AncestorType=UserControl}}" />
    </Grid>
</UserControl>

Mit dem neuen Property kann 'MyUserControl' folgenderweiße verwendet werden:

<local:MyUserControl MyContent="Hello World" />

Oder

<local:MyUserControl>
    <local:MyUserControl.MyContent>
        Hello World
    </local:MyUserControl.MyContent>
</local:MyUserControl>

(zweite Variante ist besser wenn kein Text sondern ein kompletter Control-Tree eingefügt wird).

Jetzt funktioniert es zwar, aber nur indem man beim Verwenden des Control mehr Code schreibt als nötig. Wer (so wie ich) sich daran stört unnötigen Code zu produzieren für den habe ich folgende ...

 Lösung 😀

Die Lösung ist so Simpel, allerdings wenn man es nicht weiß kann man nicht darauf kommen.

Man muss lediglich im CodeBehind von ‚MyUserControl‘ das Klassen-Attribute 'ContentPropertyAttribute' deklarieren und als Parameter das gewünschte Property als string angeben.

namespace ContentWPF
{
    [ContentProperty("MyContent")] 
    public partial class MyUserControl : UserControl
    {
        public MyUserControl()
        {
            InitializeComponent();
        }
        
        public static readonly DependencyProperty MyContentProperty
            = DependencyProperty.Register("MyContent", typeof(object), typeof(MyUserControl), null);
        public object MyContent
        {
            get { return (object)GetValue(MyContentProperty); }
            set { SetValue(MyContentProperty, value); }
        }
    }
}

Damit kann man nun im XAML-Code das Einbetten von Sub-Elementen (wie anfangs demonstriert) verwenden:

<local:MyUserControl>
    Hello World
</local:MyUserControl>

Böser Beigeschmack

Leider gibt es selbst jetzt noch einen Nachteil, den man wohl nicht umgehen kann, wenn man ein UserControl verwendet. Wenn ihr ‚MyUserControl‘ nun verwendet und einem Element darin einem Namen gebt werdet ihr vom Compiler informiert das dies nicht erlaubt ist.

<local:MyUserControl>
    <TextBlock x:Name="CompilerErrorIfItemIsNamed">Hello World</TextBlock>
</local:MyUserControl>

Folgender Fehler wird ausgegeben:

Cannot set Name attribute value 'CompilerErrorIfItemIsNamed' on element 'TextBlock'. 'TextBlock' is under the scope of element 'MyUserControl', which already had a name registered when it was defined in another scope.

Den Namen selbst kann man zwar nachträglich über CodeBehind (oder sonstwo) angeben aber zur Designzeit kann man dieses Element im CodeBehind nicht direkt ansprechen.

Wenn man damit nicht Leben kann führt kein weg an einem CustomControl vorbei. Bei diesem können eingebettete Elemente mit einem Namen versehen und vom CodeBehind direkt angesprochen werden.

Achtung: In Silverlight ist dieses Verhalten identisch, allerdings versucht euch der Compiler zu täuschen. Die Fehlermeldung wird dort nicht gezeigt und das Projekt lässt sich compilieren. Allerdings wenn Ihr zur Laufzeit im CodeBehind direkt auf das Element zugreift wird eine NullReferenceException fliegen da das Property immer leer ist.

]]>