Juli 2006 - Einträge

Vista-Style ListBox for WinXP

 

Since the WPF Style engine is very flexible you can easily achieve a Vista-like style for ListBoxes.

A vista-style ListBox in WPF

Xaml Code:

 

<ListBox>

<ListBox.ItemContainerStyle>

<Style TargetType="{x:Type ListBoxItem}">

<Setter Property="Background" Value="#00FFFFFF"/>

<Setter Property="HorizontalContentAlignment" Value="{Binding HorizontalContentAlignment, RelativeSource={RelativeSource AncestorLevel=1, Mode=FindAncestor, AncestorType={x:Type ItemsControl}}}"/>

<Setter Property="VerticalContentAlignment" Value="{Binding VerticalContentAlignment, RelativeSource={RelativeSource AncestorLevel=1, Mode=FindAncestor, AncestorType={x:Type ItemsControl}}}"/>

 

<Setter Property="Margin" Value="0,0,0,1" />

<Setter Property="Template">

<Setter.Value>

<ControlTemplate TargetType="{x:Type ListBoxItem}">

<Grid>

 

<Rectangle SnapsToDevicePixels="True" Fill="{TemplateBinding Background}" Stroke="{TemplateBinding BorderBrush}" RadiusX="4" RadiusY="4" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Width="Auto" Height="Auto" x:Name="Rectangle" />

 

<ContentPresenter Margin="10" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" x:Name="ContentPresenter" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" Content="{TemplateBinding Content}" ContentTemplate="{TemplateBinding ContentTemplate}"/>

</Grid>

<ControlTemplate.Triggers>

<Trigger Property="IsMouseOver" Value="True">

<Setter Property="Background">

<Setter.Value>

 

<LinearGradientBrush StartPoint="0,0" EndPoint="0,1">

 

<GradientStop Color="sc#1, 0.813324332, 0.9436713, 1" Offset="0.032051282051282048"/>

<GradientStop Color="sc#1, 0.7551608, 0.8902375, 0.999111533" Offset="1"/>

</LinearGradientBrush>

 

</Setter.Value>

</Setter>

<Setter Property="BorderBrush" Value="sc#1, 0.413786, 0.7415289, 0.917951047"/>

</Trigger>

 

<Trigger Property="IsSelected" Value="True">

<Setter Property="Background">

<Setter.Value>

 

<LinearGradientBrush StartPoint="0,0" EndPoint="0,1">

 

<GradientStop Color="sc#1, 0.7241676, 0.916768551, 1" Offset="0.032051282051282048"/>

<GradientStop Color="sc#1, 0.5893368, 0.8144646, 0.995921433" Offset="1"/>

</LinearGradientBrush>

 

</Setter.Value>

</Setter>

<Setter Property="BorderBrush" Value="sc#1, 0.193802863, 0.6061246, 0.828075051"/>

</Trigger>

<MultiTrigger>

<MultiTrigger.Conditions>

<Condition Property="IsSelected" Value="True"/>

<Condition Property="Selector.IsSelectionActive" Value="False"/>

</MultiTrigger.Conditions>

<Setter Property="Background">

<Setter.Value>

 

<LinearGradientBrush StartPoint="0,0" EndPoint="0,1">

 

<GradientStop Color="sc#1, 0.7241676, 0.916768551, 1" Offset="0.032051282051282048"/>

<GradientStop Color="sc#1, 0.5893368, 0.8144646, 0.995921433" Offset="1"/>

</LinearGradientBrush>

 

</Setter.Value>

</Setter>

<Setter Property="BorderBrush" Value="sc#1, 0.193802863, 0.6061246, 0.828075051"/>

</MultiTrigger>

</ControlTemplate.Triggers>

</ControlTemplate>

</Setter.Value>

</Setter>

</Style>

</ListBox.ItemContainerStyle>

 

<ListBoxItem Content="ListBoxItem1" />

<ListBoxItem Content="ListBoxItem2" />

<ListBoxItem Content="ListBoxItem3" />

</ListBox>

Posted von Jan-Cornelius Molnar mit 2 comment(s)
Abgelegt unter: ,

Coole neue Windows Live Beta Programme

Zu Microsofts neuer Plattform Windows Live gehört nicht nur der Windows Live Messenger (vorher MSN Messenger) und Windows Live Mail (Vorher MSN Hotmail) sondern auch Windows Live Mail Desktop und Windows Live Safety Center.

Windows Live Mail Desktop Beta ist eine spezielle und erweitere Version von Windows Mail (vorher Outlook Express), die neben dem Zugriff auf Emails auch die Funktionen des Windows Live Messengers integriert.

Windows Live Safety Center Beta ist ein neuer und kostenloser Service, der darauf ausgelegt ist, die Leistung und Sicherheit des PCs zu verbessern. Dieser Service beinhaltet einen Virenscanner, einen Spywarescanner und Funktionen zum Optimieren der PC Konfiguration.

 

Für die Windows Live Beta Programme kann man sich unter http://ideas.live.com anmelden.

HLS Color Selector

I searched the web for a while to find a WPF HLS Color selector like Interactive Designer is equipped with.

Since I didn’t find anything I thought about creating my own one.

The most difficult task was to convert .NET Rgb Color Values to HLS values (the difference is explained here). In my opinion the HLS color system is superior to the RGB system. After hours of searching I found a VBA sample and ported it to WPF (the code can be found at the bottom of the article).

The next thing to do was to create a new slider for the Hue and a triangle for Lightness and Saturation values.

The Slider

It was easy to create a Color Slider since it is possible to override the default template. I created a gradient from hue 0 over hue 0.1, hue 0.2 … to hue 1.0 and put it into the background. At last I restyled the value selection thumb using Interactive Designer and the result looked like this.

The Triangle

The triangle was a bit more complex than the slider since I had to start from scratch. I created the triangle shape using Paths and Interactive Designer. The I assigned 3 backgrounds with different opacity masks to it.

  1. Background Black From lower left to upper right
  2. Background White From upper left to lower right
  3. Background Colored HLS(CurrentHue, 0.5, 1) from right to left

To show the current selected Lightness and Saturation I added an ellipse.

The next step was to attach MouseDown, MouseUp and MouseMove event Handlers to the triangle. Whenever the mouse is moved over the triangle with the left button pressed the ellipse should follow. To ensure that the ellipse is moved correctly when you leave the triangle with the left button pressed I assigned Mouse.Capture(element, Element) to the element on MouseDown and Mouse.Capture(element, None) on MouseUp.

Last but not least I had to write the code that generates the appropriate color from slider and ellipse position. The complete code can be found here.

The Result

In my opinion it was worth to spent some time to create this control. I hope that more people will begin building their own controls and make them available to the public. My control is not perfect and could be done in other ways. This is article is supposed to show only one possible way.

 

Rgb <--> Hls Converter Code

Imports System.Windows.Media

 

Public Class HlsConverter

Public Shared Function ConvertFromHls(ByVal value As HlsValue) As Color

Return ConvertFromHls(value.Hue, value.Lightness, value.Saturation)

End Function

 

Public Shared Function ConvertFromHls(ByVal h As Double, ByVal l As Double, ByVal s As Double) As Color

Dim p1 As Double

Dim p2 As Double

 

Dim r As Double

Dim g As Double

Dim b As Double

 

h *= 360

 

If l <= 0.5 Then

p2 = l * (1 + s)

Else

p2 = l + s - l * s

End If

p1 = 2 * l - p2

If s = 0 Then

r = l

g = l

b = l

Else

r = QqhToRgb(p1, p2, h + 120)

g = QqhToRgb(p1, p2, h)

b = QqhToRgb(p1, p2, h - 120)

End If

 

r *= Byte.MaxValue

g *= Byte.MaxValue

b *= Byte.MaxValue

 

Return Color.FromRgb(CByte(r), CByte(g), CByte(b))

End Function

 

Public Shared Function QqhToRgb(ByVal q1 As Double, ByVal q2 As _

Double, ByVal hue As Double) As Double

If hue > 360 Then

hue = hue - 360

ElseIf hue < 0 Then

hue = hue + 360

End If

If hue < 60 Then

QqhToRgb = q1 + (q2 - q1) * hue / 60

ElseIf hue < 180 Then

QqhToRgb = q2

ElseIf hue < 240 Then

QqhToRgb = q1 + (q2 - q1) * (240 - hue) / 60

Else

QqhToRgb = q1

End If

End Function

 

Public Shared Function ConvertToHls(ByVal color As Color) As HlsValue

Dim max As Double

Dim min As Double

Dim diff As Double

Dim r_dist As Double

Dim g_dist As Double

Dim b_dist As Double

 

Dim r As Double

Dim g As Double

Dim b As Double

 

Dim h As Double

Dim l As Double

Dim s As Double

 

r = color.R / Byte.MaxValue

g = color.G / Byte.MaxValue

b = color.B / Byte.MaxValue

 

max = R

If max < G Then max = G

If max < B Then max = B

 

min = R

If min > G Then min = G

If min > B Then min = B

 

diff = max - min

L = (max + min) / 2

If Math.Abs(diff) < 0.00001 Then

s = 0

h = 0

Else

If l <= 0.5 Then

s = diff / (max + min)

Else

s = diff / (2 - max - min)

End If

 

r_dist = (max - r) / diff

g_dist = (max - g) / diff

b_dist = (max - b) / diff

 

If r = max Then

h = b_dist - g_dist

ElseIf g = max Then

h = 2 + r_dist - b_dist

Else

h = 4 + g_dist - r_dist

End If

 

h = h * 60

If h < 0 Then h = h + 360

End If

 

h /= 360

Return New HlsValue(h, l, s)

End Function

End Class

 

Public Structure HlsValue

Private mHue As Double

Private mLightness As Double

Private mSaturation As Double

 

Public Sub New(ByVal h As Double, ByVal l As Double, ByVal s As Double)

mHue = h

mLightness = l

mSaturation = s

End Sub

 

Public Property Hue() As Double

Get

Return mHue

End Get

Set(ByVal value As Double)

mHue = value

End Set

End Property

 

Public Property Lightness() As Double

Get

Return mLightness

End Get

Set(ByVal value As Double)

mLightness = value

End Set

End Property

 

Public Property Saturation() As Double

Get

Return mSaturation

End Get

Set(ByVal value As Double)

mSaturation = value

End Set

End Property

 

Public Shared Operator <>(ByVal left As HlsValue, ByVal right As HlsValue) As Boolean

Dim bool1 As Boolean

 

bool1 = left.Lightness <> right.Lightness Or left.Saturation <> right.Saturation

 

If Not bool1 Then

Return left.Hue <> right.Hue And (left.Hue > 0 And right.Hue < 1) And (left.Hue < 1 And right.Hue > 0)

Else

Return bool1

End If

End Operator

 

Public Shared Operator =(ByVal left As HlsValue, ByVal right As HlsValue) As Boolean

Dim bool1 As Boolean

 

bool1 = left.Lightness = right.Lightness And left.Saturation = right.Saturation

 

If bool1 Then

Return Math.Round(left.Hue, 2) = Math.Round(right.Hue, 2) Or (Math.Round(left.Hue, 2) = 1 And Math.Round(right.Hue, 2) = 0) Or (Math.Round(left.Hue, 2) = 0 And Math.Round(right.Hue, 2) = 1)

Else

Return False

End If

End Operator

 

Public Overrides Function ToString() As String

Return String.Format("H: {0:0.00} L: {1:0.00} S: {2:0.00}", Hue, Lightness, Saturation)

End Function

End Structure

Posted von Jan-Cornelius Molnar mit no comments
Abgelegt unter: ,