Custom ListBox in WPF - c#

I am trying to create a custom ListBox control in WPF for a chat Messenger. I am using an ellipse to show the online/offline user. The ellipse is to be displayed on left and some text in center of the ListBoxItem.
I want to set the ellipse fill propert to red/green based on some variable.
This is what I have done :
<ListBox Name="myList" HorizontalAlignment="Left" Height="232" Margin="117,74,0,0" VerticalAlignment="Top" Width="207">
<ListBox.ItemTemplate>
<DataTemplate>
<DockPanel>
<Ellipse Name="ellipse" Fill="Red" DockPanel.Dock="Left">
<Ellipse.Triggers>
<Trigger Property="{Binding Online}" Value="True">
<Setter TargetName="ellipse" Property="Ellipse.Fill" Value="Green"/>
</Trigger>
</Ellipse.Triggers>
</Ellipse>
<TextBlock Text="{Binding text}"></TextBlock>
</DockPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
and in the code :
myList.Items.Add(new { text="Hello",Online="True" });
I am getting an error as
Cannot find the static member 'FillProperty' on the type 'ContentPresenter'.
What am I doing wrong here?

Obviously this is wrong: Property="{Binding Online}"
Also you should use a Style for triggers, no need to set TargetName, and you need to take precedence into consideration, and use a Setter for the default value.

you are actually misleading WPF with some of these concerns.
Binding A property on trigger will not work. you have to use DataTrigger insteed of Triggers.
Implementing Trigger on the Fly for any control. most of the times not work. So go with Styles.
While you are creating Ellipse in template make sure you have created enough size for it. So that can be visible to users.
try this.
<Window.Resources>
<Style x:Key="elstyle" TargetType="Ellipse">
<Setter Property="Height" Value="5"/>
<Setter Property="Width" Value="5"/>
<Setter Property="Fill" Value="Red"/>
<Style.Triggers>
<DataTrigger Binding="{Binding Online}" Value="true">
<Setter Property="Fill" Value="Green"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Window.Resources>
<Grid>
<ListBox x:Name="myList" HorizontalAlignment="Left" Height="232" Margin="117,74,0,0" VerticalAlignment="Top" Width="207">
<ListBox.ItemTemplate>
<DataTemplate>
<DockPanel>
<Ellipse Name="ellipse" Margin="5" DockPanel.Dock="Left" Style="{DynamicResource elstyle}">
</Ellipse>
<TextBlock Text="{Binding Name}"></TextBlock>
</DockPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
code behind .
public MainWindow()
{
Random r = new Random();
InitializeComponent();
for (int i = 0; i < 10; i++)
{
myList.Items.Add(new { Name = "Name" + i.ToString(), Online = Convert.ToBoolean(r.Next(-1, 1)) });
}
}

You need to set the initial colour via a Setter and not in XAML. For more information and see this question: Change the color of ellipse when mouse over

there are a few issues in your XAML
set the size of your Ellipse
you need to use Style instead of Ellipse.Triggers
set your Fill color in your Style if you wane be able to change it in XAML by some condition
here an working example for your problem
<DataTemplate>
<!--<DockPanel> juste because i like StackPanel-->
<StackPanel Orientation="Horizontal">
<!--<Ellipse Name="ellipse" Fill="Red" DockPanel.Dock="Left">-->
<Ellipse Name="ellipse" Width="15" Height="15">
<!--<Ellipse.Triggers>-->
<Ellipse.Style>
<Style TargetType="Ellipse">
<Setter Property="Fill" Value="Red"/>
<Style.Triggers>
<!--<Trigger Property="{Binding Online}" Value="True">-->
<DataTrigger Binding="{Binding Online}" Value="True">
<Setter Property="Fill" Value="LimeGreen"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Ellipse.Style>
</Ellipse>
<TextBlock Text="{Binding text}"/>
</StackPanel>
</DataTemplate>

Related

ListBox display multiple selected items

I have here a ListBox which shall show serveral items where some of them are selected.
<ListBox IsEnabled="False" x:Name="SecondaryModelSelector" SelectionMode="Extended" SelectedItem="{Binding Path=DataContext.SelectedSecondaryModels, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ContentControl}, Mode=OneWay}" ItemsSource="{Binding Path=DataContext.AvailableModels, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ContentControl}}" >
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Label Content="{Binding Name}" Margin="5,0,5,0"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
The selected items are set in a ComboBox and thus the ListBox is disabled and Mode=OneWay to disable selection in the ListBox itself.
The Template looks like this:
<Style x:Key="MyListBoxItem" TargetType="ListBoxItem">
<Setter Property="SnapsToDevicePixels" Value="true" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBoxItem">
<Border x:Name="Border" Padding="2">
<ContentPresenter />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="true">
<Setter TargetName="Border" Property="Background" Value="Blue"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="MyListBoxBorder" TargetType="{x:Type ListBox}">
<Setter Property="ItemContainerStyle" Value="{StaticResource MyListBoxItem}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBox">
<Border x:Name="OuterBorder">
<ScrollViewer Margin="0" Focusable="false">
<StackPanel Margin="2" IsItemsHost="True" />
</ScrollViewer>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
The problem is now, that I cannot display multiple selected items, i.e. the background does not turn blue. Showing only one selected item is no problem.
Works (but shows only one selected item...)
public Cpu SelectedSecondaryModels
{
get { return SelectedGlobalVariable.SecondaryModels.FirstOrDefault(); }
}
Does not work:
public ObservableCollection<Model> SelectedSecondaryModels
{
get { return new ObservableCollection<Model>(SelectedGlobalVariable.SecondaryModels); }
}
I have no errors, so how can I show multiple selected items?
I tried SelectedItems instead of SelectedItem instead, but this is read-only field.
When I allow to select items in the ListBox than the blue background appears, and binding throws errors as there is no setter method.
The SelectedItem property cannot be bound to a collection of several items to be selected.
And as you have already noticed, SelectedItems is a read-only property.
You could use an attached behaviour to work around this. Please refer to this blog post and this example for more information about how to do this.
You will also find some solutions here:
Bind to SelectedItems from DataGrid or ListBox in MVVM

WPF ToolTip Text Alignment

I have the following ListViewItem:
<GridViewColumn Width="{Binding ActualWidth,
RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Grid}},
Converter={StaticResource MathConverter}, ConverterParameter=(x/10)*1}">
<GridViewColumn.Header>
<GridViewColumnHeader Content=" Total Fees "
HorizontalContentAlignment="Right" />
</GridViewColumn.Header>
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding GarnishmentTotals.TotalFees, StringFormat={}{0:c}}"
TextAlignment="Right" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
The Style for this item is as follows:
<Style x:Key="MultipleGarnishmentsStyle" TargetType="ContentControl">
<Style.Triggers>
<DataTrigger Binding="{Binding Garnishments.Count, Converter={StaticResource GreaterThanEqualToBooleanConverter}, ConverterParameter=2}" Value="True"
h:TriggerTracing.TriggerName="MultipleGarnishmentsStyle_Trigger1"
h:TriggerTracing.TraceEnabled="True">
<!-- Leave the content alone and just change the format string -->
<Setter Property="TextBlock.FontWeight" Value="UltraBold" />
<Setter Property="ToolTip" Value="Employee has multiple garnishments. Double click to view details." />
</DataTrigger>
</Style.Triggers>
</Style>
I am having an issue with the alignment of the text within the ToolTip.
The text seems to be using the ListViewItems text alignment (Right). I have tried adding the following properties to teh style but nothing changes:
<Setter Property="TootlTip.HorizontalAlignment" Value="Left" />
<Setter Property="TootlTip.HorizontalContentAlignment" Value="Left" />
<Setter Property="TootlTip.Width" Value="300" />
Is there a way to either increase the ToolTip width so there is no wrapping of the text or make the ToolTip text left aligned.
I got the same problem and after some digging (RibbonToolTip is inheriting alignment from a textbox), I found a solution. It maybe late, but it would benefit others.
What you need to do is to setup you ToolTip style like this:
<Style TargetType="ToolTip">
<Setter Property="TextBlock.TextAlignment" Value="Left"/>
</Style>
Since Tooltip is a ContentControl you can customize its content as you want. Consider the following example:
<Grid>
<Button Content="Hi there!">
<Button.Style>
<Style TargetType="Button">
<Setter Property="ToolTip">
<Setter.Value>
<ToolTip MaxWidth="100" HorizontalContentAlignment="Center">
<TextBlock Text="fsdfasdfasdfasdfasdfasdfadsfasdf fadsfadsf adfa fdasfasdfasdfa adfasd" TextAlignment="Center" HorizontalAlignment="Center" TextWrapping="Wrap"/>
</ToolTip>
</Setter.Value>
</Setter>
</Style>
</Button.Style>
</Button>
</Grid>
You can play around with the content's properties (in this case the TextBlock) in order to achieve the final look you want.

WPF ComboBox EditTemplate - TextBox border is not going away

I am using a DEVExpress combobox and have enabled type ahead (Auto search functioanlity). In combo box I am showing two things. First item is an image and second item is a value(id).
Mine problem is that the value border is getting outside to combo box while showing at UI at run time. I tried setting margin but its of no use. My application is having option to select theme and for some of the theme its getting hazy.
Any idea how to get rid of this ?
see the first one is looking fine however the below one is bit hazy if i change the theme.
I am using below code for the same.
<dvEx:ComboBoxEdit.EditTemplate>
<ControlTemplate>
<StackPanel Orientation="Horizontal">
<Image Source="{Binding Path=(dxe:BaseEdit.OwnerEdit).SelectedItem.Image, RelativeSource={RelativeSource Self}}" Margin="8, 0, 4, 0"/>
<TextBox x:Name="PART_Editor" BorderBrush="Transparent"/>
</StackPanel>
</ControlTemplate>
</dvEx:ComboBoxEdit.EditTemplate>
<dvEx:ComboBoxEdit.ItemTemplate>
<DataTemplate DataType="{x:Type vm:DesignSelectViewModel}">
<StackPanel Orientation="Horizontal">
<Image Source="{Binding Image}" Margin="8, 0, 4, 0"/>
<TextBlock Text="{Binding Name}"/>
</StackPanel>
</DataTemplate>
</dvEx:ComboBoxEdit.ItemTemplate>
To accomplish your task I suggest you to override the TextBox.Template as follows to make it theme-independent and remove it's focused state (border and background):
<TextBox x:Name="PART_Editor">
<TextBox.Template>
<ControlTemplate TargetType="{x:Type TextBox}">
<Grid x:Name="Root" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}">
<ScrollViewer x:Name="PART_ContentHost" Margin="1" Padding="{TemplateBinding Padding}"/>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsReadOnly" Value="True">
<Setter Property="Opacity" TargetName="PART_ContentHost" Value="0.75"/>
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Opacity" TargetName="Root" Value="0.5"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</TextBox.Template>
</TextBox>
Related MSDN article: TextBox Styles and Templates

Change Images on Custom CheckBox in WPF

All I have created the following custom CheckBox which uses images instead of a CheckBox. This works well however, I want to be able to change the images as required. Ideally I would like to use application resources Properties.Resources.SomeImage16 (a .png file). The XAML is
<Style x:Key="styleCustomCheckBox"
TargetType="{x:Type CheckBox}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type CheckBox}">
<StackPanel Orientation="Horizontal">
<Image x:Name="imageCheckBox"
Width="16"
Height="16"
Source="F:\Camus\ResourceStudio\Graphics\Images\UnPinned16.png"/>
<ContentPresenter VerticalAlignment="Center"/>
</StackPanel>
<ControlTemplate.Triggers>
<Trigger Property="IsChecked" Value="False">
<Setter TargetName="imageCheckBox"
Property="Source"
Value="F:\Camus\ResourceStudio\Graphics\Images\Pinned16.png"/>
</Trigger>
<Trigger Property="IsChecked" Value="True">
<Setter TargetName="imageCheckBox"
Property="Source"
Value="F:\Camus\ResourceStudio\Graphics\Images\UnPinned16.png"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
With implementation
<ListBox SelectionMode="Single" >
<StackPanel Orientation="Horizontal">
<CheckBox Style="{StaticResource styleCustomCheckBox}"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Margin="4,0,4,0"/>
<TextBlock VerticalAlignment="Top"
Text="SomeRecentDocument.resx"/>
</StackPanel>
</ListBox>
How can I change the images used for the custom CheckBox (i.e. change the pinned/un-pinned to tick/cross etc.) without having to create a new style/template?
Thanks for your time.
As already mentioned #HighCore the need for the ability to use vector graphics. In this case, to use the Path, where in Data to the specified coordinates on which the object is drawn (MSDN).
Advantages:
Do not store it in the files, smaller size
Dynamically changing color, size and the whole shape
Minuses (in my opinion):
You can not always find the right Data for the Path
About minus: There are special sites (www.modernuiicons.com) and utilities for converting the image to Data.
Change the style of CheckBox using the Path:
Style
<Style x:Key="styleCustomCheckBox" TargetType="{x:Type CheckBox}">
<Setter Property="FontFamily" Value="Verdana" />
<Setter Property="FontSize" Value="14" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type CheckBox}">
<StackPanel Orientation="Horizontal">
<Path x:Name="MyPin" Width="18" Height="18" Stretch="Fill" Fill="#FF000000"
Data="F1 M 56.1355,32.5475L 43.4466,19.8526C 42.7886,20.4988 42.298,21.2123 41.9749,21.9932C 41.6519,22.7741 41.4903,23.5729 41.4903,24.3895C 41.4903,25.1942 41.6529,25.987 41.9779,26.7679L 34.0577,34.6821C 33.3918,34.3372 32.6991,34.0776 31.9796,33.9032C 31.2601,33.7288 30.5298,33.6415 29.7885,33.6415C 28.623,33.6415 27.4953,33.8526 26.4052,34.2748C 25.315,34.697 24.3419,35.3342 23.4856,36.1865L 30.2344,42.9174L 25.9027,47.9032L 22.6532,51.8425L 20.5988,54.5836C 20.1212,55.2892 19.8823,55.753 19.8823,55.975L 19.8645,56.0701L 19.9002,56.088L 19.9002,56.1474L 19.9358,56.1058L 20.0131,56.1236C 20.2351,56.1236 20.6989,55.8888 21.4045,55.419L 24.1457,53.3765L 28.0849,50.1151L 33.0945,45.7775L 39.8016,52.5025C 40.6579,51.6462 41.2961,50.6731 41.7163,49.5829C 42.1365,48.4928 42.3466,47.367 42.3466,46.2056C 42.3466,45.4603 42.2603,44.729 42.0879,44.0115C 41.9155,43.294 41.6548,42.6003 41.3069,41.9304L 49.2202,34.0161C 50.0011,34.3372 50.7939,34.4978 51.5986,34.4978C 52.4192,34.4978 53.2189,34.3362 53.9979,34.0132C 54.7768,33.6901 55.4894,33.2015 56.1355,32.5475 Z "/>
<ContentPresenter VerticalAlignment="Center" Margin="10,0,0,0" />
</StackPanel>
<ControlTemplate.Triggers>
<Trigger Property="IsChecked" Value="False">
<Setter TargetName="MyPin" Property="Data" Value="F1 M 32.3691,30.2225L 33.2253,29.3901L 15.361,11.5258C 13.9814,12.7067 12.6951,13.9936 11.5148,15.3738L 26.6252,30.4842C 27.743,30.1631 28.8767,30.0025 30.0263,30.0025C 30.8191,30.0025 31.6,30.0759 32.3691,30.2225 Z M 45.5039,49.3629L 60.6292,64.4826C 62.0123,63.2996 63.3017,62.0101 64.4846,60.6268L 46.6218,42.7866L 45.7834,43.619L 45.9439,44.7726L 45.9915,45.9261L 45.8785,47.6713L 45.5039,49.3629 Z M 56.1355,32.5475L 43.4466,19.8526C 42.7886,20.4987 42.298,21.2123 41.9749,21.9932C 41.6519,22.7741 41.4903,23.5729 41.4903,24.3895C 41.4903,25.1942 41.6529,25.987 41.9779,26.7679L 34.0577,34.6821C 33.3918,34.3372 32.6991,34.0776 31.9796,33.9032C 31.2601,33.7288 30.5298,33.6415 29.7885,33.6415C 28.623,33.6415 27.4953,33.8526 26.4052,34.2748C 25.315,34.697 24.3419,35.3342 23.4856,36.1865L 30.2344,42.9174L 25.9027,47.9032L 22.6532,51.8425L 20.5988,54.5836C 20.1212,55.2892 19.8823,55.753 19.8823,55.975L 19.8645,56.0701L 19.9002,56.0879L 19.9002,56.1474L 19.9358,56.1058L 20.0131,56.1236C 20.2351,56.1236 20.6989,55.8888 21.4045,55.419L 24.1457,53.3765L 28.0849,50.1151L 33.0945,45.7775L 39.8016,52.5025C 40.6579,51.6462 41.2961,50.6731 41.7163,49.5829C 42.1365,48.4928 42.3466,47.367 42.3466,46.2056C 42.3466,45.4603 42.2603,44.729 42.0879,44.0115C 41.9155,43.294 41.6548,42.6003 41.306,41.9304L 49.2202,34.0161C 50.0011,34.3372 50.7939,34.4978 51.5986,34.4978C 52.4192,34.4978 53.219,34.3362 53.9979,34.0132C 54.7768,33.6901 55.4894,33.2015 56.1355,32.5475 Z " />
<Setter TargetName="MyPin" Property="Fill" Value="Gray" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Using
<StackPanel Orientation="Vertical" HorizontalAlignment="Center">
<CheckBox Height="35"
Style="{StaticResource styleCustomCheckBox}"
Content="MySolution1" />
<CheckBox Height="35"
Style="{StaticResource styleCustomCheckBox}"
Content="MySolution2" />
</StackPanel>
Output
We can also store the Path's in resources, and refer to them as like this:
<Path x:Key="MyPath" Data="F1 M 38,19C 48.4934,19 57,27.5066 ... />
...
<Setter TargetName="MainPath" Property="Data"
Value="{Binding Source={StaticResource MyPath}, Path=Data}" />
Edit
To specify arbitrary icons, I created two attached dependency properties (string type):
IsCheckedOnData
IsCheckedOffData
IsCheckedOnData contains Data value by IsChecked = "True", IsCheckedOffData value by IsChecked = "False".
Now you need only to determine the strings of icons and define such a resource (for example).
Full example:
XAML
<Window x:Class="CustomCheckBoxHelp.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:CustomCheckBoxHelp"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
WindowStartupLocation="CenterScreen"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<sys:String x:Key="Up">
F1 M 37.8516,35.625L 34.6849,38.7917L 23.6016,50.2708L
23.6016,39.9792L 37.8516,24.9375L 52.1016,39.9792L 52.1016,
50.2708L 41.0182,38.7917L 37.8516,35.625 Z
</sys:String>
<sys:String x:Key="Down">
F1 M 37.8516,39.5833L 52.1016,24.9375L 52.1016,35.2292L
37.8516,50.2708L 23.6016,35.2292L 23.6016,24.9375L 37.8516,39.5833 Z
</sys:String>
<Style x:Key="styleCustomCheckBox" TargetType="{x:Type CheckBox}">
<Setter Property="FontFamily" Value="Verdana" />
<Setter Property="FontSize" Value="14" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type CheckBox}">
<StackPanel Orientation="Horizontal">
<Path x:Name="MyPin" Width="18" Height="18" Stretch="Fill" Fill="#FF000000"
Data="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(local:CustomCheckBoxClass.IsCheckedOnData)}" />
<ContentPresenter VerticalAlignment="Center" Margin="10,0,0,0" />
</StackPanel>
<ControlTemplate.Triggers>
<Trigger Property="IsChecked" Value="False">
<Setter TargetName="MyPin" Property="Data"
Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(local:CustomCheckBoxClass.IsCheckedOffData)}" />
<Setter TargetName="MyPin" Property="Fill" Value="Gray" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<Grid>
<StackPanel Orientation="Vertical" HorizontalAlignment="Center" Background="Beige">
<CheckBox Height="35"
local:CustomCheckBoxClass.IsCheckedOnData="{StaticResource Up}"
local:CustomCheckBoxClass.IsCheckedOffData="{StaticResource Down}"
Style="{StaticResource styleCustomCheckBox}"
Content="MySolution1" />
<CheckBox Height="35"
local:CustomCheckBoxClass.IsCheckedOnData="{StaticResource Up}"
local:CustomCheckBoxClass.IsCheckedOffData="{StaticResource Down}"
Style="{StaticResource styleCustomCheckBox}"
Content="MySolution2" />
</StackPanel>
</Grid>
</Window>
Code behind
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
}
public class CustomCheckBoxClass : DependencyObject
{
#region IsCheckedOnDataProperty
public static readonly DependencyProperty IsCheckedOnDataProperty;
public static void SetIsCheckedOnData(DependencyObject DepObject, string value)
{
DepObject.SetValue(IsCheckedOnDataProperty, value);
}
public static string GetIsCheckedOnData(DependencyObject DepObject)
{
return (string)DepObject.GetValue(IsCheckedOnDataProperty);
}
#endregion
#region IsCheckedOffDataProperty
public static readonly DependencyProperty IsCheckedOffDataProperty;
public static void SetIsCheckedOffData(DependencyObject DepObject, string value)
{
DepObject.SetValue(IsCheckedOffDataProperty, value);
}
public static string GetIsCheckedOffData(DependencyObject DepObject)
{
return (string)DepObject.GetValue(IsCheckedOffDataProperty);
}
#endregion
static CustomCheckBoxClass()
{
PropertyMetadata MyPropertyMetadata = new PropertyMetadata(string.Empty);
IsCheckedOnDataProperty = DependencyProperty.RegisterAttached("IsCheckedOnData",
typeof(string),
typeof(CustomCheckBoxClass),
MyPropertyMetadata);
IsCheckedOffDataProperty = DependencyProperty.RegisterAttached("IsCheckedOffData",
typeof(string),
typeof(CustomCheckBoxClass),
MyPropertyMetadata);
}
}
Note: In the style I have not used TemplateBinding because TemplateBinding doesn’t work outside a template or outside its VisualTree property, so you can’t even use TemplateBinding inside a template’s trigger. Therefore, we must use the construction {RelativeSource TemplatedParent} and a Path equal to the dependency property whose value you want to retrieve.
Sorry, I don't yet know how to reference an image in those resources, but if you can add the images into a folder named Images in your application root directory, then you will be able to reference the images simply like this:
<Image Source="/ApplicationName;component/Images/SomeImage16.png" />
As you mention you can change the checkbox trigger by checked and unchecked. And the image will display corresponding trigger. Your xml code is good for me.I just remove the trigger true portion.because the false portion by default in focus and after click the checkbox image UnPinned16.png is visible. And agan click image Pinned16.png is visibale .
<Style x:Key="styleCustomCheckBox"
TargetType="{x:Type CheckBox}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type CheckBox}">
<StackPanel Orientation="Horizontal">
<Image x:Name="imageCheckBox"
Width="16"
Height="16" Source="F:\Camus\ResourceStudio\Graphics\Images\UnPinned16.png"/>
<ContentPresenter VerticalAlignment="Center"/>
</StackPanel>
<ControlTemplate.Triggers>
<Trigger Property="IsChecked" Value="False">
<Setter TargetName="imageCheckBox"
Property="Source"
Value="F:\Camus\ResourceStudio\Graphics\Images\Pinned16.png"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
And I am using this checkbox under a textblock
<CheckBox Style="{StaticResource styleCustomCheckBox}"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Margin="4,0,4,0"/>

WPF ItemsControl IsMouseOver not working as expected

I have the following code in the Window.Resources of a WPF window. What it is basically doing is creating an item that represents a grid with a label positioned on the left and a button on the right. When I mouse over the label or the button the row changes color as expected but I want it to also change color if the mouse is over any of the row.
How can this be achieved?
Any help is appreciated.
<Window.Resources>
<dtos:ProjectDto x:Key="data"/>
<Style x:Key="alternatingWithTriggers"
TargetType="{x:Type ContentPresenter}">
<Setter Property="Height" Value="25"></Setter>
</Style>
<Style x:Key="onmouseover" TargetType="{x:Type DockPanel}">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="Yellow">
</Setter>
</Trigger>
</Style.Triggers>
</Style>
<DataTemplate x:Key="ItemTemplate">
<Border x:Name="ItemBorder" HorizontalAlignment="Stretch" BorderThickness="0" Background="#BBB" ClipToBounds="True" >
<DockPanel ClipToBounds="True" HorizontalAlignment="Stretch" Style="{StaticResource onmouseover}">
<Label Content="{Binding Name}" HorizontalAlignment="Left" Height="80"></Label>
<Button Content="Delete" HorizontalAlignment="Right" Margin="0,0,10,0"/>
</DockPanel>
</Border>
...
Give the DockPanel Background="Transparent". That should allow it to capture mouse events.
I don't see anything obviously wrong in the snippet you've posted, and since I'm not in front of Studio, I can't try it out, but if I were you, I'd try adding a MouseEnter handler on the DockPanel (just throw the do-nothing handler in the code-behind for the view, since you'll remove it later).
Make sure that handler is getting hit when you enter, and with the debugger/immediate window, make sure the IsMouseOver property is as you expect it to be. That will at least direct your next debugging steps:
If IsMouseOver is true and your handler is hit, then my guess would be something about the trigger you've got set up isn't quite right.
If IsMouseOver is false or your handler isn't hit, then my guess would be something like IsHitTestVisible is set to false or something of that sort.
Just for fun, I'd also try moving the style declaration inline to the dockpanel, just to make sure, like so:
<DataTemplate x:Key="ItemTemplate">
<Border x:Name="ItemBorder" HorizontalAlignment="Stretch" BorderThickness="0" Background="#BBB" ClipToBounds="True" >
<DockPanel ClipToBounds="True" HorizontalAlignment="Stretch">
<DockPanel.Style>
<Style TargetType="{x:Type DockPanel}">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="Yellow"/>
</Trigger>
</Style.Triggers>
</Style>
</DockPanel.Style>
<Label Content="{Binding Name}" HorizontalAlignment="Left" Height="80"></Label>
<Button Content="Delete" HorizontalAlignment="Right" Margin="0,0,10,0"/>
</DockPanel>
</Border>

Categories

Resources