The MouseBinding Tag in XAML is declaring a property „Gesture“, but it is hard to find a full reference / a complete list for all gestures of the MouseBinding tag.
Solution
Accepted gestures can be found in the enumeration MouseAction
When you right click a folder in the Windows Explorer and you choose „TortoiseSVN -> Show log“ you are not able to see all entries. Even when you change the date range on the upper right of the window you can not fetch all entries.
It seems like that older SVN Server History entries are deleted. But in fact this is not the case.
Solution
First check the date range on the upper right of the window.
After that try to fetch the „lost“ entries by pressing the „Show All“ button on the lower left of the window.
Um die Klasse List<T> vor Zugriffen zu schützen / zu beschränken oder diese mit Notification-Events (z.B. ObservableCollection) auszustatten werden für den jeweiligen Verwendungszweck eigene Collections verwendet.
Ansatz
Um eine eigene Collection zu erstellen, welche mit foreach( … ) über die Elemente der eingekapselten Struktur (also z.B. List<T>) zu iterieren, benötigt man eine Enumerator-Klasse, welche die Methoden …
MoveNext()
Reset()
… und die Property „Current“ implementiert
implementiert (hier MyCollectionEnumerator) … sowie natürlich die gecustomizte Collection-Klasse selber, die die Datenstruktur enthält (hier MyCollection).
Lösung
using System;
using System.Collections.Generic;
namespace Irrsinn
{
// Diese Klasse definiert mit MoveNext / Reset und der Property
// Current aus dem Interface IEnumerator wie foreach(String s in col)
// über die eingekapselte Liste iterieren darf.
public class MyCollectionEnumerator : System.Collections.IEnumerator
{
private List<string> StringList;
private int Counter = -1;
// Im Konstruktor wird die Liste übergeben um die Operationen
// MoveNext / Reset / Current darauf ausführen zu können
public MyCollectionEnumerator(List<string> _StringList)
{
this.StringList = _StringList;
}
// Geht auf den nächsten Datensatz, der in der Liste
// gespeichert ist. Wenn MoveNext() false zurückgibt
// ist das Ende der Liste erreicht
public bool MoveNext()
{
Counter++;
return Counter < StringList.Count;
}
// Setzt die Collection zurück.
public void Reset()
{
Console.WriteLine("RESET!");
Counter = -1;
}
// Gibt immer das aktuelle Element zurück, was mit
// MoveNext erreicht wurde
public object Current
{
get
{
return StringList[Counter];
}
}
}
public class MyCollection
{
// Intern ist sind Collections meistens vom Typ List<T>
// aber die eigene Implementierung gibt uns die Möglichkeit
// den Zugriff auf die Liste anzupassen.
private List<string> _StringList = new List<string>();
// Hinzufügen eines Strings
public void AddString(string newString)
{
this._StringList.Add(newString);
}
// GetEnumerator wird benötigt um mit foreach(...)
// über die Collection zu iterieren
public System.Collections.IEnumerator GetEnumerator()
{
return new MyCollectionEnumerator(_StringList);
}
}
class Program
{
static void Main(string[] args)
{
// Gecustomizte Collection
MyCollection myCol = new MyCollection();
myCol.AddString("Schatzi schenk mir ein Foto");
myCol.AddString("schenk mir ein Foto vom Bier");
myCol.AddString("Schatzi schenk mir ein Foto");
myCol.AddString("Dann schenk ich Dir auch eins");
myCol.AddString("vom Tier (also von den Muppets)");
foreach (string s in myCol)
{
Console.WriteLine(s);
}
Console.ReadLine();
}
}
}
RelayCommand (s) erfüllen den Zweck von Actions / Delegates und sind somit Funktionszeiger die es erlauben, zu einem späteren Zeitpunkt eine Methode aufzurufen.
Sie implementieren das Interface ICommand, welches von den WPF Controls genutzt wird, um bei Bedarf die Execute()-Methode aufzurufen. D.h. die Execute()-Methode soll nur dann aufgerufen werden, wenn das WPF Control das Ereignis tatsächlich auslöst und nicht bereits zur Bindung.
Ohne RelayCommands müsste man für jeden Command eine eigene Klasse schreiben, welche vom Interfache ICommand erbt. Sie helfen somit Code einzusparen.
Verwendung in einem MVVM Pattern
Häufige Verwendung: In einer XAML Datei wird ein Button definiert, der an einen RelayCommand gebunden wird, welcher zu einem späteren Zeitpunkt aufgerufen werden soll:
Das ViewModel, welches die View instanziert, muss einen RelayCommand „PerformCalibration“ definieren, der erst aufgerufen wird, wenn der Button geklickt wird (Relay) und nicht sofort bei der Bindung an den ButtonCommand.
Für diesen Zweck beinhaltet das ViewModel, welches die View instanziert, eine Funktion die den RelayCommand zurückgibt:
Der Button ruft die Funktion „Execute“ des implementierten RelayCommands auf, wenn er geklickt wird.
Da RelayCommands „Actions“ sind, haben Sie keinen Rückgabewert.
Beispiel: public delegate string MeinDelegateName(string s);
Ein Delegate deklariert einen Datentyp (hier MeinDelegateName) anhand einer Funktionssignatur. Eine Funktionssignatur, welche den Aufbau einer Funktion darstellt, sieht folgendermaßen aus:
Rückgabewert DelegateName (Argumente)
Diesem Datentyp kann nun eine oder mehrere(siehe +=-Operator) Funktionen mit genau dieser Funktionssignatur zugewiesen werden, was das Aufrufen dieser Funktionen ermöglicht, ohne deren Namen zu kennen. Dadurch wird die Implementierung der Funktion von dem aufrufendem Code entkoppelt.
Ein Verwendungsbeispiel wären EventListener / Events, welchen über Delegates die Funktion übergeben wird, die beim Eintritt des Events aufgerufen werden soll. Über den += Operator können einem Event mehrere Funktionen zugewiesen werden (z.B. bei einem Windows-Fenster das OnLoad-Event).
Bei der Verwendung von Delegates muss also der Delegate-empfangende Code den Namen der Funktion (bzw. Methode) nicht wissen und kann diese trotzdem aufrufen. Delegates anonymisieren also Funktions- bzw. Methodennamen. Ein ähnlicher Mechanismus für Klassen stellen Interfaces zur Verfügung. Interfaces anonymisieren allerdings nicht per se Namen der deklarierten Methoden/Funktionen sondern lediglich der Klassennamen. Wäre eine Anonymisierung von Funktions- und Methodennamen gewünscht, könnten die Delegates in den Interfaces deklariert werden.
Deklaration von Delegate-Typen mit dem normalen Delegate-Schlüsselwort
// Definition des Delegatentyps SageHalloWeltDelegate:
// Eine Funktionssignatur, welcher ein string übergeben
// wird und welche einen String zurückgibt, wird festgelegt
public delegate string SageHalloWeltDelegate(string s);
public string sageHalloWeltFunktion(string s)
{
Console.Write("Hallo");
return " Welt";
}
public Program()
{
// Instanz der Funktion "delegateInstanzDerFkt" mit der
// Funktionssignatur "SageHalloWeltDelegate"
SageHalloWeltDelegate delegateInstanzDerFkt = sageHalloWeltFunktion;
// Aufruf der instanzierten Funktion
Console.WriteLine(delegateInstanzDerFkt("Hallo"));
}
Durch .NET vordefinierte Delegattypen: Action / Func / Predicate
.NET enthält jedoch eine Reihe von Delegattypen, die Programmierer verwenden können, damit sie keine neuen Typen (wie oben der Typ „SageHalloWeltDelegate„) erstellen müssen. Diese Typen lauten Func<>, Action<> und Predicate<>.
Die Deklarationszeile des Delegate-Typs public delegate string SageHalloWeltDelegate(string s); fällt somit weg.
Action<> wird verwendet, wenn eine Aktion mithilfe der Argumente des Delegaten ausgeführt werden muss. Die von dem Typ gekapselte Methode gibt keinen Wert zurück. Die Signatur darf maximal 16 Argumente enthalten.
Bsp. für eine Action Action<string> delegateInstanzDerFkt= sageHalloWeltFunktion;
Hier würde der Teil “ Welt“ aus dem obigen Beispiel nicht zurückgegeben werden.
Func<> wird üblicherweise verwendet, wenn eine Transformation ausgeführt werden muss, Sie also die Argumente des Delegaten in ein anderes Ergebnis transformieren müssen. Projektionen sind ein gutes Beispiel. Die von dem Typ gekapselte Methode gibt einen angegebenen Wert zurück. Die Signatur darf maximal 16 Argumente enthalten.
Bsp. für Rückgabewert „string“ und Übergabewert „string“: Func<string, string> delegateInstanzDerFkt= sageHalloWeltFunktion;
Der letzte Typparameter der Func-Deklaration ist jeweils der Rückgabewert. Func<string, string, int> delegateInstanzDerFkt= sageHalloWeltFunktion; würde einen Integer-Wert zurückgeben und ihr würden zwei Strings übergeben werden.
Predicate<> wird verwendet, wenn Sie ermitteln müssen, ob das Argument die Bedingung des Delegaten erfüllt. Sie können auch die Schreibweise Func<T, bool> verwenden. In diesem Fall gibt die Methode einen booleschen Wert zurück. Predicates werden meistens bei LINQ verwendet, wenn man zum Beispiel in Collections oder Listen etwas suchen möchte. Meistens wird Predicate dann als LAMBDA-Ausdruck geschrieben. Die Signatur darf maximal 16 Argumente enthalten.
Func<string, bool> delegateInstanzDerFkt= sageHalloWeltFunktion; ist also äquivalent mit Predicate<string>delegateInstanzDerFkt= sageHalloWeltFunktion; und würde mit dem obigen Beispiel zu einem Fehler führen, da die Methode sageHalloWeltFunktion einen String zurückgibt.
Konvertieren von Lamda-Ausrücken in Delegateinstanzen
// Berechne quadrat
Func<int, int> square = x => x * x;
Console.WriteLine(square(5));
// Konkateniere String
Func<string, string, string> concat = (a,b) => a + " " + b;
concat("Hello", "World");
// Einzelne Action wird ohne Übergabeparameter (Rückgabe hat sie nicht)
Action line = () => Console.WriteLine("Hello world!");
line();
// Einzelne Action wird ohne Übergabeparameter (Rückgabe hat sie nicht)
Action line = text => Console.WriteLine(text);
line("Hello world!");
Visual Basic for application does not have function to test, whether a string starts with or ends with another string like it is included in the .NET Framework
Approach
Those function can easily created by using the existing string functions
Solution
The following code can be pasted to a VBA project:
Public Function EndsWith(str As String, ending As String) As Boolean
Dim endingLen As Integer
endingLen = Len(ending)
EndsWith = (Right(Trim(UCase(str)), endingLen) = UCase(ending))
End Function
Public Function StartsWith(str As String, start As String) As Boolean
Dim startLen As Integer
startLen = Len(start)
StartsWith = (Left(Trim(UCase(str)), startLen) = UCase(start))
End Function
Example usage:
If StartsWith(„My string has something in it“, „My string“) Then Msg Box „It is in it!“ If EndsWith(„My string has something in it“, „in it“) Then Msg Box „It is in it!“
Sometimes it happens, that you have created folders in Visual Studio for your application and had put some *.cs C# Source Code files that suddenly disappeard in the solution explorer.
Analysis
I.e. that can happen when you have forgotten to save your Visual Studio application project, berfore you have closed the IDE.
Solution
Use the file explorer and navigate to your Visual Studio solution (alternatively you can right-click a source code file in your folder and select „Open contained folder“ from the context menu).
Open the .csproj file in your solution in a text editor of your choice:
.csproj files store the project structure of the solution explorer
Go to the section where the <ItemGroup /> tags are declared and add a new section with the folders and source code files you want to show in your solution like in the screenshot below
My folders Command, ViewModelBase, ViewModel and Model disappeard over night, so i readded the marked group
You can add all cs-files with a wildcard star like it is shown in the screenshot above.
According to the .NET documentation the Ribbon Control should be available since WPF 4.5, what means is available since .NET Framework 4.5 . But you can not find it? Are you even thinking about the download of the Ribbon control for older versions? Not necessary, please see the following points…
Approach
We have to find out the right moment when it is generally possible to use the Ribbon control.
The following table shows, that the first version of WPF (3.0) was released with the .NET Framework 3.0. As you can see the version number of WPF is maintained synchron with the version number of the .NET framework.
WPF Version
Release (YYYY-MM)
.NET Version
Visual Studio Version
Major Features
3.0
2006-11
3.0
N/A
Initial Release. WPF development can be done with VS 2005 (released in Nov 2005) too with few additions as described here.
3.5
2007-11
3.5
VS 2008
Changes and improvements in: Application model, data binding, controls, documents, annotations, and 3-D UI elements.
3.5 SP1
2008-08
3.5 SP1
N/A
Native splash screen support, New WebBrowser control, DirectX pixel shader support. Faster startup time and improved performance for Bitmap effects.
4.0
2010-04
4.0
VS 2010
New controls: Calendar, DataGrid, and DatePicker. Multi-Touch and Manipulation
4.5
2012-08
4.5
VS 2012
New Ribbon control New INotifyDataErrorInfo interface
4.5.1
2013-10
4.5.1
VS 2013
No Major Change
4.5.2
2014-05
4.5.2
N/A
No Major Change
4.6
2015-07
4.6
VS 2015
Transparent child window support HDPI and Touch improvements
Which WPF Version is included in which version of the .NET Framework?
Solution
When you have installed at least .NET Framework 4.5 you can Add the Reference „System.Windows.Control.Ribbon“ as follows:
1.) Expand the tree in in your Solution Explorer of you WPF application
2.) Right-click the „Add References“ entry and choose „Add Reference“
In the Solution Explorer of your WPF Application right-click the References entry and choose „Add Reference“
3.) In the following dialog search for „Ribbon“ in the search field on the upper right
Search for Ribbon in the Dialog that appears by using the textbox on the upper right corner
4.) After that you should be able to add the reference by using the checkbox
5.) In your XAML Code you are now able to use the <Ribbon/> Tag
Optional: 6.) If you want to use a RibbonWindow instead of a WPF Window which allows you to have the Quick Access Controls at the top of the window, you have to do the declaration in the head of MainWindow.xaml as follows:
<ribbon:RibbonWindow x:Class="WPFTutorial.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:ribbon="clr-namespace:System.Windows.Controls.Ribbon;assembly=System.Windows.Controls.Ribbon"
Title="WPF Layoutmanager" Height="399" Width="763">
<DockPanel LastChildFill="True">
<Ribbon DockPanel.Dock="Top" >
</Ribbon>
<!-- Put the last Child here -->
</DockPanel>
</ribbon:RibbonWindow>
Additionally you have to change the base class name in the code behind window and add the using System.Windows.Controls.Ribbon :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Ribbon;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace WPFTutorial
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : RibbonWindow
{
public MainWindow()
{
InitializeComponent();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
MessageBox.Show("Test");
}
}
}
Like in HTML/CSS there are different source code locations where it is possible to apply appearance styles to WPF controls. In this article i want to make a really short summary of those points.
Approach
The following examples are showing the declaration places for styles in the order from local control styles to global application styles