-
ACHTUNG - NEUES BLOG
Ab sofort steht unter http://devtyr.norberteder.com mein neues Blog zur Verfügung. Dieses Blog wird nicht weiter betreut, bleibt aber erhalten. Neue Eintr%auml;ge erfolgen nur mehr im neuen Blog. Kommentare werden ebenfalls nicht mehr behandelt. Wer weiterhin meinen Einträgen und Aktivitäten folgen möchte, möge bitte RSS-Feeds, Verlinkungen etc. an die neue Location anpassen.
|
WPF: BringToFront und SendToBack
19.11.07 - .NET, WPF Beitrag von Norbert Eder| | Unter Windows Forms gibt es die Methoden BringToFront und SendToBack um Controls in den Vordergrund zu bringen oder in den Hintergrund zu setzen. Diese Methoden sind in der Windows Presentation Foundation nicht mehr vorhanden. Bei der WPF verfügt jedes Element über eine ZOrder (quasi ein Index, welcher den Verlauf über die Z-Achse beschreibt). Elemente die später hinzugefügt werden, besitzen einen höheren Index und sind somit auf der Z-Achse höher oben angesiedelt und liegen daher über Elementen niedrigerer Ordnung.
Um nun BringToFront und SendToBack zur Verfügung zu stellen, muss die ZOrder manuell angepasst werden. Dies wird mit nachfolgender Methode gezeigt.
private void ChangeZOrder(bool bringToFront)
{
int iNewIndex = -1;
Canvas parentElement = (Canvas)_parentElement;
if (bringToFront)
{
foreach (UIElement elem in parentElement.Children)
if (elem.Visibility != Visibility.Collapsed)
++iNewIndex;
}
else
{
iNewIndex = 0;
}
int iOffset = (iNewIndex == 0) ? +1 : -1;
int iElemCurIndex = Canvas.GetZIndex(this);
foreach (UIElement child in parentElement.Children)
{
if (child == this)
Canvas.SetZIndex(this, iNewIndex);
else
{
int iZIndex = Canvas.GetZIndex(child);
if (bringToFront && iElemCurIndex < iZIndex ::
!bringToFront && iZIndex < iElemCurIndex)
{
Canvas.SetZIndex(child, iZIndex + iOffset);
}
}
}
}
Hierbei ist folgendes zu beachten: In dieser Methode wird auf das Element _parentElement zugegriffen. Hintergrund ist der, dass die Methode (in meinem Fall) in einer Basisklasse für spezielle Controls definiert wurde und mittels der beiden nachfolgenden Methoden in allen entsprechenden Controls zur Verfügung steht. Genauso könnte es eine Ableitung des Containers (in diesem Fall ein Canvas) geben, dem mitgeteilt wird, welches Child manipuliert werden soll.
public void BringToFront()
{
ChangeZOrder(true);
}
public void SendToBack()
{
ChangeZOrder(false);
}
Gegenenfalls muss hier an die eigenen Bedürfnisse angepasst werden, es passiert jedoch nichts Aufregendes. Im Falle von SendToBack wird als ZIndex 0 gesetzt, d.h. das Element ist anschließend das erste auf dem Container und wird ganz hinten angezeigt, im Falle von BringToFront geht's in die andere Richtung.
Noch ein kleiner Hinweis: muss das Parent-Objekt gesucht werden, kann dies damit erledigt werden:
UIElement parent = VisualTreeHelper.GetParent(myElement);
| | | Kommentar hinzufügen
| 0 Trackbacks
| Permalink | Trackback-URL |
WPF: Element innerhalb eines Canvas per Sourcecode positionieren
16.11.07 - .NET, WPF Beitrag von Norbert Eder| | Von den Windows-Forms ist man ja noch die Eigenschaft Location gewohnt. Diese gibt es bei WPF nicht mehr, stattdessen muss man einen anderen Weg gehen.
Per XAML wird ein Element in einem Canvas recht einfach exakt positioniert:
<Canvas x:Name="LayoutRoot" Background="Yellow">
<ListBox
Width="100"
Height="100"
Canvas.Left="352"
Canvas.Top="192"
IsSynchronizedWithCurrentItem="True"/>
</Canvas>
Doch wie wird das per Code gemacht? Eigentlich auch nicht wirklich schwieriger, man muss eben nur wissen wie:
Canvas canvas=new Canvas();
canvas.Background=Brushes.Yellow;
ListBox lbx=new ListBox();
lbx.Width=100;
lbx.Height=100;
lbx.IsSynchronizedWithCurrentItem=true;
Canvas.SetLeft(lbx,352);
Canvas.SetTop(lbx,192);
canvas.Children.Add(lbx);
An vielen Stellen ist also dann doch ein Umdenken notwendig und ich ertappe mich anscheinend selbst noch oft bei meinem alten Denkschema.
| | | Kommentar hinzufügen
| 0 Trackbacks
| Permalink | Trackback-URL |
Ein paar Zahlen rund um Microsoft
14.11.07 - Kunterbunt Beitrag von Norbert Eder| | Man mag ja zu Microsoft stehen wie man möchte. Aber die hier genannten Zahlen sind schon mehr als imposant.
- 10.000 Server im Firmen-Netzwerk
- 130.000 Server für Windows Live Services
- 600.000 Laufwerke
- 85 Webserver für microsoft.com
- 26 Millionen Emails täglich
- usw.
Nette Zahlen. Vor allem die 97% Spam aller externen Emails (=19,4 Millionen Spam Emails täglich) sind schon eine nette Menge. Jetzt wundert es mich nicht mehr, dass Microsoft an einem verbesserten Spam-Filter (Zusammenarbeit mit der Aids-Forschung) arbeitet ...
... zusätzlich frage ich mich natürlich:
- Können diese Zahlen stimmen?
- Wer administriert all diese Server?
- Welche Kosten fallen nur für die Administration an?
- usw.
| | | 2 Kommentare
- 764 mal angesehen
| 0 Trackbacks
| Permalink | Trackback-URL |
.NET Snippets startet den 2. Snippet-Wettbewerb
14.11.07 - .NET, Allerlei, Internet, Community Beitrag von Norbert Eder| |
Worum geht es?
Gesucht werden sogenannte Codesnippets, dies sind keine kompletten Programme, sondern Quelltextausschnitte. Ob Einzeiler oder komplette Klassen, wichtig ist, dass es sich um sinnvollen Code handelt, der auch von anderen Entwicklern wieder verwendet werden kann.
Der Themenbereich, aus dem der Snippet stammt, ist dabei nicht relevant. Möglich wären zum Beispiel: Multimedia, ASP.NET, Winforms, Dateisystem, Datenbank usw.
Es können nur Snippets in den .NET Sprachen C#, VB.NET, J#, C++.NET oder ASP.NET eingereicht werden.
Preise
- 1. Preis: Visual Studio 2008
- 2. Preis: Red Gate ANTS Profiler Professional
- 3. Preis: CodeRush™ with Refactor!™ Pro
- 4. Preis: Jahresabo der dotnetpro
- 5. Preis: Ein Gutschein im Wert von 50€ für den Online-Buchversand Terrashop
Teilnahme-Zeitraum
Gestartet wird am 15. November 2007.
Der Einsendeschluss ist der 31. Dezember 2007 (00:00 Uhr).
Weitere Informationen
Weitere Informationen auf .NET Snippets
| | | 5 Kommentare
- 761 mal angesehen
| 0 Trackbacks
| Permalink | Trackback-URL |
Code-Dokumentation einfach gemacht!
14.11.07 - Entwicklung, Diskussionen, Qualitätsmgmt., .NET, Grundlagen, Visual Studio, Allerlei, Tools, 3rd Party Tools Beitrag von Norbert Eder| | Die Dokumentation des Sourcecodes ist ein wichtiger - aber leider oft vernachlässigter - Bestandteil der Softwareentwickler. Vor allem Frameworks wollen gut dokumentiert werden, damit ein beliebiger Entwickler sofort damit loslegen kann, ohne sich lange einarbeiten zu müssen.
Nun ist es so, dass Visual Studio hier nicht besonders viel mitbringt. Lediglich das Schreiben der Kommentare in XML-Files, die später via IntelliSense eingebunden werden. Ein Tool zur Generierung von Hilfe-Dateien wird nicht über die IDE zur Verfügung gestellt. Aber es gibt auch andere Lösungen.
Benötigte Tools/Frameworks
Bevor mit der Generierung der Sourcecode-Dokumentation gestartet werden kann, müssen einige Frameworks/Tools installiert werden. Zentraler Bestandteil für diese Variante ist Sandcastle. Hier nun eine Liste der zu installierenden Produkte:
Hinweise: Der HTML Help Workshop ist nur für die Generierung von HTML 2.x Dokumentationen notwendig und muss nur installiert werden, wenn sich dieser noch nicht auf dem Rechner befindet.
Installation
Die ersten beiden Produkte kommen jeweils als MSI-Pakete daher. Daher sind diese sehr einfach in der Installation. Der HTML Workshop kann normal herunter geladen werden und muss nur in der Projekt-Konfiguration im Sandcastle Help File Builder in der Eigenschaft HtmlHelp2xCompilerPath angegeben werden. Nun noch GhostDoc installieren und schon ist man fast fertig.
Vorarbeiten
Wichtig ist, dass beim Build-Prozess XML-Kommentare ebenfalls generiert werden. Dazu ist die Einstellung in den Eigenschaften der jeweiligen Assemblies unter dem Punkt Build zu setzen.
Nun müssen natürlich auch noch sämtliche Kommentare geschrieben werden. Um sich viel Arbeit zu ersparen kann nun GhostDoc eingesetzt werden. Dieses unterstützt bei der Generierung der Dokumentation und liefert auch Vorschläge, die in einigen Fällen noch weiter angepasst werden müssen, aber grundsätzlich ist damit eine solide Basis geschaffen.
Generierung der Dokumentation
Mit Hilfe der Sandcastle Help File Builder GUI kann nun auf einfache Art und Weise ein Dokumentations-Projekt angelegt werden. Hierzu sind die notwendigen Assemblies anzugeben. Die vorhandenen XML-Dateien werden automatisch hinzugeladen und müssen daher nicht extra angegeben werden.
Wurden nun beispielsweise Frameworks á la NUnit, NLog etc. verwendet wird der Builder beim Ausführen beanstanden, dass referenzierte Assemblies nicht gefunden werden können. Anstatt diese über Add hinzuzufügen, empfiehlt es sich, diese im Builder unter Dependencies einzupflegen.
Nun müssen noch Einstellungen getroffen werden, welche Templates für Generierung verwendet werden, ob 1.x, 2.x generiert werden soll, oder gar eine Website und viele weitere Einstellungen wie Überschriften usw.
Ein wichtiger Punkt ist unter Namespaces zu finden: Hier ist es möglich einzustellen, welche Namespaces in der Dokumentation aufscheinen und es kann zusätzlich eine Beschreibung für diese eingegeben werden.
Wurde alles konfiguriert, kann die Generierung gestartet werden. Diese dauert zwar ein wenig länger als man erwartet, dafür ist das Ergebnis (vorausgesetzt es wurde brav dokumentiert) sehr fein und kann für die Weitergabe oder interne Verwendung herangezogen werden.
Fazit
Mit Hilfe dieser wenigen Tools und ca. 10 - 15 Minuten Installation und Konfiguration kann ein komplettes Dokumentations-System aufgesetzt werden. Die Dokumentation selbst kann uns leider niemand abnehmen, aber das soll keine Ausrede sein. Ich persönlich setze obige Kombination schon länger ein und bin bis dato sehr zufrieden.
Sicherlich wird es Möglichkeiten geben, dies weiter zu verbessern, wer hier also eine andere Konfiguration einsetzt bzw. Vorteile für seine Lösung anbieten kann, der sei hiermit eingeladen, mir dies mitzuteilen. Ebenfalls würde mich interessieren, ob ihr Code-Dokumentationen schreibt, oder nicht, inklusive einer kurzen Begründung.
| | | Kommentar hinzufügen
| 0 Trackbacks
| Permalink | Trackback-URL |
Local History Feature unter Visual Studio 2005
13.11.07 - .NET, Visual Studio, Tools, 3rd Party Tools Beitrag von Norbert Eder| | Unter Eclipse gibt es ein nettes Feature welches sich Local History nennt. Beim Speichern einer geänderten Klasse wird im Hintergrund ein Version dieser Datei mit Zeitstempel in einen History-Container gelegt. Werden nun erneut Änderungen gemacht, die eventuell umfangreich sind und durch einen Gedankenfehler eventuell rückgängig gemacht werden wollen (inzwischen bereits einige Male gespeichedrt), kann eine alte Version aus der lokalen History bezogen werden und der alte Stand ist somit wieder hergestellt.
Diese Funktion fehlt bei Visual Studio und daher hatte ich bereits an ein kleines Projekt diesbezüglich gedacht. Glücklicherweise habe ich mich jedoch vorher auf die Suche gemacht und ein wirklich nettes Add-In für Visual Studio gefunden:
Visual Local History 2005
Aufgepasst: Das Add-In ist noch im Beta-Stadium und daher ist Vorsicht geboten.
| | | Kommentar hinzufügen
| 0 Trackbacks
| Permalink | Trackback-URL |
Geschafft es ist!
11.11.07 - Blog-Intern Beitrag von Norbert Eder| | "Es" ist geschafft und ich auch. Nach zwei Tagen heftigen Umzuges kann ich mich nun endlich in meiner neuen Wohnung austoben. Es hat sich ja nun schon über mehrere Wochen hingezogen, viel musste erledigt werden, aber jetzt nimmt hoffentlich bald wieder alles normale "Formen" an und es wird wieder etwas ruhiger.
Fotos gibt es keine, denn dieses Chaos möchte ich niemandem zumuten :)
| | | 6 Kommentare
- 784 mal angesehen
| 0 Trackbacks
| Permalink | Trackback-URL |
Oktober 2007 im Rückblick
07.11.07 - .NET, Grundlagen, Base Framework, WPF, Allerlei Beitrag von Norbert Eder
WPF: ListBox um Grafiken/Images erweitern
07.11.07 - .NET, WPF Beitrag von Norbert Eder| | Die Standard-ListBox unter WPF ist dann ein doch eher fades Steuerelement. In den meisten Fällen wird man mit den angebotenen Möglichkeiten nicht auskommen, daher muss es angepasst bzw. erweitert werden. Dieser Artikel zeigt, welche Schritte vorgenommen werden müssen, um folgendes Aussehen zu erhalten:
Normalerweise werden mit Hilfe der ListBox ListBoxItems (es können auch andere Child-Elemente sein) angezeigt. Diese besitzen eine Eigenschaft Content. Darüber kann nun der anzuzeigende Text dargestellt werden. Für dieses Beispiel werden jedoch zwei Strings benötigt und ein Image.
Betreffend der Strings können wir ein simples Datenobjekt erstellen und an die ListBox binden.
using System;
using System.Collections.Generic;
using System.Text;
namespace ListBoxSampleApp
{
public class DataItem
{
private string _title = null;
private string _description = null;
public string Title
{
get { return this._title; }
set { this._title = value; }
}
public string Description
{
get { return this._description; }
set { this._description = value; }
}
public DataItem() { }
public DataItem(
string title,
string description)
{
_title = title;
_description = description;
}
}
}
Die Bindung der Daten als auch das Einbinden der Grafik erfolgt an der gleichen Stelle. Hierzu muss eine Ressource erstellt werden, in der ein DataTemplate definiert wird. Dieses Template beschreibt in unserem Fall das Aussehen eines Eintrages in der ListBox.
<Window.Resources>
<DataTemplate x:Key="ListItemTemplate">
<StackPanel>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="32"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Image
Source="GoLtrHS.png"
Grid.Column="0"
Grid.RowSpan="2"/>
<TextBlock
Text="{Binding Path=Title}"
Grid.Column="1"
Grid.Row="0"
FontWeight="Bold"/>
<TextBlock
Text="{Binding Path=Description}"
Grid.Column="1"
Grid.Row="1" />
</Grid>
</StackPanel>
</DataTemplate>
</Window.Resources>
Wie zu sehen ist wird der Eintrag für unsere ListBox aus einem StackPanel und einem Grid erzeugt. Das Grid besitzt insgesamt zwei Zeilen und zwei Spalten. In der ersten Spalte wird nun unsere Grafik angezeigt (die Grafik wurde in das Projekt eingefügt und steht somit zur Verfügung). Durch die Angabe der RowSpan erstreckt sich die Grafik über beide Zeilen. In der zweiten Spalte ist für jede Zeile ein TextBlock zu finden. Diese enthalten jeweils ein Binding auf Eigenschaften aus dem zuvor definierten Datenobjekt: einmal für den Titel und einmal für die Beschreibung.
Wenn dieser Schritt erledigt ist, muss nur noch der ListBox mitgeteilt werden, dass das erstellte Template für die Anzeige der Items verwendet werden soll. Dies geschieht in der Eigenschaft ItemTemplate der ListBox.
<ListBox
RenderTransformOrigin="0.5,0.5"
Cursor="Arrow"
x:Name="MainListBox"
Background="#FFFFFFE0"
BorderBrush="#FFCCCCCC"
BorderThickness="1,1,1,1"
FontFamily="Arial"
FontSize="16"
IsSynchronizedWithCurrentItem="True"
Margin="8,8,8,29"
d:LayoutOverrides="GridBox"
ItemTemplate="{StaticResource ListItemTemplate}">
</ListBox>
Um dies testen zu können, müssen nur noch Testdaten erstellt und an die ItemSource-Eigenschaft der ListBox gebunden werden.
[html]
public Window1()
{
this.InitializeComponent();
Fillup();
}
private void Fillup()
{
List<DataItem> itemList = new List<DataItem>();
DataItem di1 = new DataItem("Testeintrag", "Beschreibung zum Item");
DataItem di2 = new DataItem("Testeintrag 2", "Beschreibung zum Item");
itemList.Add(di1);
itemList.Add(di2);
MainListBox.ItemsSource = itemList;
}
Fertig ist die angepasste WPF-ListBox.
| | | 2 Kommentare
- 963 mal angesehen
| 0 Trackbacks
| Permalink | Trackback-URL |
WPF: Bewegliche Grid-Spalten - GridSplitter Beispiel
06.11.07 - .NET, WPF Beitrag von Norbert Eder| | Wer braucht sie nicht? Vergrößerbare Bereiche. Mit Hilfe des GridSplitters kann dies sehr einfach gelöst werden. Hierzu sind die entsprechenden Spalten (funktioniert auch auf Zeilen) zu definieren und ein GridSplitter zu verwenden. Dem GridSplitter muss nun noch mitgeteilt werden, zwischen welchen Spalten er sich befindet. Hier gleich ein Beispiel:
<Window x:Class="GridSplitterSample.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="GridSplitterSample"
Height="300"
Width="300">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Label Background="Yellow" Grid.Column="0"/>
<GridSplitter Grid.Column="0" Width="2" />
<Label Background="Green" Grid.Column="1"/>
</Grid>
</Window>
Wer dies testen möchte: eine leere WPF-Anwendung erstellen und den obigen Sourcecode in die Window1.xaml kopieren, starten und probieren. Das Ergebnis sieht übrigens so aus:
Durch den Splitter können nun die einzelnen Spaltengrößen verändert werden:
| | | 2 Kommentare
- 694 mal angesehen
| 0 Trackbacks
| Permalink | Trackback-URL | Zurück Weiter
|
|
|
|
|
|
|