Biggle's Blog

Web- und Software Development

by Mario Binder

MultiBinding die Zweite

Ich hatte schon vor einiger Zeit gezeigt (puh, schon wieder 1 1/2 Jahre her..) , wie man im XAML ein MultiBinding implementiert. Nun stand ich vor einem Problem, das ich im XAML ein paar Elemente definiere und im Code weitere Elemente zur Laufzeit hinzufüge. Diese Elemente wollte ich nun vernünftig zusammenbringen.

Im Code benötige ich eine Slider-Property und eine Property Namens “Caption”, welche einen Text halten soll. Im Xaml habe ich ein TextBlock-Element, welcher den Inhalt der Caption-Property und den aktuellen Wert des Sliders anzeigen soll.

1
2
public string Caption { get; set; }
public Slider Slider { get; set; }
1
<TextBlock Grid.ColumnSpan="3" Name="CaptionTxtBlock" />

Der Slider, welcher von aussen gesetzt wird, bekommt im “Loading” noch ein paar Eigenschaften und die Position im UserControl mit:

1
2
3
4
Slider.Name = "slider";
Slider.SetValue(Grid.RowProperty, 1);
Slider.SetValue(Grid.ColumnProperty, 1);
SliderGrid.Children.Add(Slider);

Anschliessend baue ich mir ein MultiBinding-Objekt, dass nun die beiden benötigen Properties an meiner TextProperty des TextBlockes bindet und entsprechend formatiert ausgibt:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
MultiBinding mb = new MultiBinding()
{
    Mode = BindingMode.TwoWay,
    UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged,
    StringFormat = "{0} ({1:00} %)"
};
 
Binding sliderBinding = new Binding()
{
    Source = Slider,
    Path = new PropertyPath("Value")
};
 
Binding captionBinding = new Binding()
{
    Source = this,
    Path = new PropertyPath("Caption")
};
 
mb.Bindings.Add(captionBinding);
mb.Bindings.Add(sliderBinding);
 
BindingOperations.SetBinding(CaptionTxtBlock, TextBlock.TextProperty, mb);

Und so sieht das ganze dann aus:

Download Code

Viel Spaß beim entwickeln : )

by Mario Binder

Text innerhalb eines TextBlock-Controls formatieren – XAML

Um einen Text innerhalb einer Textbox zu formatieren, steht einem die Klasse Run zur Verfügung. Run ist ein Element für fortlaufenden Inhalt auf Inlineebene, das formatierten oder unformatierten Lauftext enthalten kann.

1
2
3
4
<TextBlock FontSize="28" TextWrapping="Wrap">
    Hier steht <Run Foreground="Red">Text</Run> der
    <Run FontWeight="Bold" FontStyle="Italic" Foreground="Cyan" FontSize="38" TextDecorations="Underline">verschiedene Formate</Run> darstellt.
</TextBlock>

Einen Zeilenumbruch innerhalb eines Textblocks erreicht man mit

<LineBreak />

Bei einem Hyperlink kann diese Methode auch angewendet werden. (In Silverlight HyperlinkButton)

1
2
3
4
5
6
7
<TextBlock TextWrapping="Wrap">            
    <Hyperlink TextDecorations="None" NavigateUri="http://www.biggle.de">
        <Italic>Hier</Italic> <Bold>steht</Bold> ein <Underline>Hyperlink</Underline>                 
        <LineBreak />      
            über mehrere <Run Foreground="Red">Zeilen</Run>.
    </Hyperlink>
</TextBlock>

Im Hyperlinkbeispiel sieht man auch, wie man den Text kursiv,  fett geschrieben und unterstrichen, noch formatieren kann.

Selbst Bilder können so in einem TextBlock mit dargestellt werden:

1
2
3
4
5
<TextBlock>
    Das bin ich
    <LineBreak />
    <Image Source="/Images/IMG_6911_small.jpg" Width="50" />
</TextBlock>

Es ist auch möglich, innerhalb des Textblock-Controls Werte aus einem Binding heraus darzustellen:

1
2
3
4
5
6
7
8
9
<TextBlock DataContext="{Binding Order}" TextWrapping="Wrap">
    <Run TextDecorations="Underline">Ihre Bestellung</Run>
    <LineBreak />
    <Run>Produkt:</Run>
    <TextBlock Text="{Binding productName}" />
    <Run>(</Run>
        <TextBlock Text="{Binding quantity}" />
    <Run>)</Run>
</TextBlock>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public partial class MainWindow : Window
{
    public Order Order { get; set; }
 
    public MainWindow()
    {
        InitializeComponent();
        LoadOrders();
    }  
    private void LoadOrders()
    {
        Order = new Order();
        Order.productName = "Mountainbike";
        Order.quantity = 1;
 
        this.DataContext = this;
    }
}


Viel Spaß beim entwickeln : )

by Mario Binder

Eigenes Hyperlink Control – XAML

Der eine oder andere hat dies sicher schon bemerkt. Wenn man im XAML ein Hyperlink Element einsetzt und NavigateUri mit der entsprechenden Adresse definiert, könnte man annehmen, dass das ausreicht um den Link aufzurufen. Doch leider ist dem nicht so.

Man könnte aber sein eigenes Control schreiben, welches diese Funktionalität beinhaltet.

Dazu fügt man ein neues UserControl hinzu und benennt dieses “Link“. Dieses UserControl muss nun so abgeändert werden, dass dieses von Hyperlink ableitet. Im Xaml muss der Knoten UserControl in Hyperlink umbenannt und im code-behind muss das UserControl auch dahingehend abgeändert werden.

1
2
3
4
5
<Hyperlink x:Class="WPFSpielwiese.Link"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
 
</Hyperlink>

Nun registrieren wir uns am Event “RequestNavigate” und implementieren einen einfachen Process.Start um die URL aus NavigateUri aufzurufen. Die Fehlerbehandlung lass ich an dieser Stelle mal weg.

1
2
3
4
5
6
7
8
9
10
11
12
13
public partial class Link : Hyperlink
{
    public Link()
    {
        InitializeComponent();
        this.RequestNavigate += new RequestNavigateEventHandler(Link_RequestNavigate);
    }
 
    void Link_RequestNavigate(object sender, RequestNavigateEventArgs e)
    {
        Process.Start(this.NavigateUri.ToString());
    }
}

Eingesetzt wird das ganze dann wie folgt:

1
2
3
4
5
xmlns:mp="clr-namespace:WPFSpielwiese"
..
<TextBlock>
    <mp:Link NavigateUri="http://www.biggle.de">Biggle's Blog</mp:Link>
</TextBlock>


Viel Spaß beim entwickeln : )

by Mario Binder

Einfaches CSS Image-RollOver ohne Javascript

Hier ein kleines CSS Snippet, was man sicher öfter mal gebrauchen kann. Mit diesem Snippet erreicht man ein simples Imgage-RollOver, wo das Bild durch ein anderes ausgetauscht wird, wenn man mit der Mouse drüber fährt. Einfach deshalb, weil man sonst immer nur Beispiele mit fetten Javascriptcode findet, wenn man das mal braucht…

 

1
<a title="Facebook" class="img_rollover" href="http://www.facebook.com/MarioPriebe"></a>
1
2
3
4
5
6
7
8
9
10
/*CSS für ImageRollOver  */
a.img_rollover:link, .img_rollover{
	width:32px;
	height:32px;
        display:block;
	background-image:url(images/icon32_facebook_off-2.png);
}
a.img_rollover:hover{
	background-image:url(images/icon32_facebook_on.png);
}

Möchte man mehrere Icons / Images nebeneinander abbilden, setzt man noch ein float:left; in die Definition.

Viel Spaß beim entwickeln : )

by Mario Binder

Verwenden von SoundPlayerAction und SoundPlayer- WPF Quicky

Sounds mit WPF abspielen kann man über der Klasse SoundPlayerAction. Implementiert werden kann das ganze sowohl im Xaml als auch im Code.

Im Xaml:

1
2
3
4
5
6
7
<Button Content="Play Sound">
    <Button.Triggers>
        <EventTrigger RoutedEvent="Button.Click">
            <SoundPlayerAction Source="pack://siteoforigin:,,,/Media/Windows Exclamation.wav" />
        </EventTrigger>
    </Button.Triggers>
</Button>

Im Xaml muss der Pfad zur Datei mit absoluter Angabe oder als siteoforgin-Datei (Inhalt, immer kopieren) angeben werden.

Im Code ist die Instanzierung der Klasse SoundPlayer und der Methodenaufruf Play ausreichend:

1
2
SoundPlayer sp = new SoundPlayer("Media/Windows Exclamation.wav");
sp.Play();

Auch hier muss das entsprechende Mediafile über den Eigenschaften immer in das Ausgabeverzeichnis kopiert werden.

Die Mediadatei kann über ein Dateipfad, einer Url und von einem Stream aus geladen werden.

Ergänzend sollte ich noch erwähnen, das die Klasse SoundPlayer, welche im Code implementiert wird, mehrere Methoden zum Abspielen von Sounddateien hat. Zum einen die genannte Play, welche das File asynchron abspielt. Die Methode PlaySync hingegen spielt das ganze synchron ab und mit PlayLooping wird das Mediafile in einer Endlosschleife abgespielt. Über der Methode Stop wird das Abspielen abgebrochen.

Standardmässig wird das File erst beim ersten Abspielen geladen, über die Methoden Load und LoadAsync kann dieser Vorgang im Voraus gemacht werden. Das Event LoadCompleted wird gefeuert, wenn das File geladen wurde.

Abgespielt werden können mit den Klassen SoundPlayerAction und SoundPlayer lediglich *.wav Dateien.

Viel Spaß beim entwickeln : )

by Mario Binder

Escape-Sequenz in XAML

Möchte man im XAML in einem Attribut z.B. Text oder Content geschweifte Klammern verwenden,

muss man diese entsprechend escapen. Hier verwendet man vor dem eigentlichen Inhalt zwei geschweifte Klammern {}

<TextBlock Text="{}{Welt}" />

Wird der Text mit weiteren Text außerhalb der geschweiften Klammern kombiniert, macht XAML das automatisch

<TextBlock Text="Hallo {Welt}" />