Again I'm a bit lost in WPF treeview.
I populated my treeview with some data and I'd like to fire a command, when clicking on a node and get its values in that command.
My treeview-xaml looks like this:
<TreeView DataContext="{Binding ProjectTree}" ItemsSource="{Binding ProjectNode}" DockPanel.Dock="Left" Margin="0 0 2 0" x:Name="ProjectTree" Grid.Column="0">
<TreeView.ItemContainerStyle>
<Style TargetType="{x:Type TreeViewItem}">
<Setter Property="IsExpanded" Value="{Binding IsExpanded, Mode=TwoWay}"/>
<Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay}"/>
<Setter Property="FontWeight" Value="Normal"/>
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="FontWeight" Value="Bold"/>
</Trigger>
</Style.Triggers>
</Style>
</TreeView.ItemContainerStyle>
<TreeView.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding Children}">
<StackPanel Orientation="Horizontal">
<Image Margin="3" Source="{Binding ItemType, Converter={x:Static misc:TreeItemImageConverter.Instance }}" Width="20" />
<TextBlock VerticalAlignment="Center" Text="{Binding Name}"/>
</StackPanel>
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
How can I trigger a command on click on a treeviewitem here?
SOLUTION
After some experiments, It works for me that way:
xaml:
<TreeView DataContext="{Binding ProjectTree}" ItemsSource="{Binding ProjectNode}" DockPanel.Dock="Left"
x:Name="ProjectTree" Margin="0 0 2 0" Grid.Column="0">
<i:Interaction.Triggers>
<i:EventTrigger EventName="SelectedItemChanged">
<i:InvokeCommandAction Command="{Binding TreeNodeSelected}"
CommandParameter="{Binding ElementName=ProjectTree, Path=SelectedItem}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
<TreeView.ItemContainerStyle>
<Style TargetType="{x:Type TreeViewItem}">
<Setter Property="IsExpanded" Value="{Binding IsExpanded, Mode=TwoWay}"/>
<Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay}"/>
<Setter Property="FontWeight" Value="Normal"/>
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="FontWeight" Value="Bold"/>
</Trigger>
</Style.Triggers>
</Style>
</TreeView.ItemContainerStyle>
<TreeView.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding Children}">
<StackPanel Orientation="Horizontal">
<Image Margin="3" Source="{Binding ItemType, Converter={x:Static misc:TreeItemImageConverter.Instance }}" Width="20" />
<TextBlock VerticalAlignment="Center" Text="{Binding Name}"/>
</StackPanel>
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
In the Viewmodel of the treeview:
C#
public RelayCommand TreeNodeSelected { get; private set; }
readonly ReadOnlyCollection<PlcAddressViewModel> _rootNodes;
readonly PlcAddressViewModel _rootAddress;
#region Constructor
public ProjectTreeviewModel(PlcAddress rootAddress)
{
_rootAddress = new PlcAddressViewModel(rootAddress);
_rootNodes = new ReadOnlyCollection<PlcAddressViewModel>(
new PlcAddressViewModel[]
{
_rootAddress
});
TreeNodeSelected = new RelayCommand(ExecuteTreeNodeSelected, canExecuteMethod);
}
#endregion Constructor
#region Commands
private bool canExecuteMethod(object parameter)
{
return true;
}
private void ExecuteTreeNodeSelected(object parameter)
{
PlcAddressViewModel selectedNode = (PlcAddressViewModel)parameter;
Console.WriteLine("Found this node: " + selectedNode.Name);
return;
}
#endregion Commands
Thanks to #mm8 and #BionicCode
You could handle an event like for example SelectedItemChanged using an interaction trigger:
<TreeView DataContext="{Binding ProjectTree}"
ItemsSource="{Binding ProjectNode}"
x:Name="ProjectTree"
xmlns:i="http://schemas.microsoft.com/xaml/behaviors">
<i:Interaction.Triggers>
<i:EventTrigger EventName="SelectedItemChanged" >
<i:InvokeCommandAction Command="{Binding MouseEnterCommand}" />
</i:EventTrigger>
</i:Interaction.Triggers>
<TreeView.ItemContainerStyle>
...
</TreeView.ItemContainerStyle>
...
</TreeView>
Handling events in an MVVM WPF application
How to add System.Windows.Interactivity to project?
But why don't you just bind the SelectedItem property to a source property and handle your logic in the setter of this one? This would be MVVM way of doing this.
Edit: Since the SelectedItem property a TreeView is read-only, you'll have to use a behaviour to be able to bind to it. There is an example of how to do this here.
Related
I need to bind a command (RelayCommand) of my ViewModel with the click event on an element of the conetxtmenu for a treeviewitem
ViewModel Command
private RelayCommand _myElementCommand;
public RelayCommand MyCommand
{
get
{
return _myElementCommand?? (_myElementCommand= new RelayCommand(
x =>
{
//LoadData();
MessageBox.Show("Clicked!");
}));
}
}
VIEW
<TreeView x:Name="tvUBR" ItemsSource="{Binding UBRList, UpdateSourceTrigger=PropertyChanged}">
<TreeView.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding Children}">
<StackPanel Orientation="Horizontal">
<TextBlock VerticalAlignment="Center" Text="{ Binding Description }">
<TextBlock.Style>
<Style TargetType="TextBlock">
<Setter Property="Foreground" Value="Black" />
<Style.Triggers>
<DataTrigger Binding="{Binding IsMatch}"
Value="True">
<Setter Property="Foreground" Value="Green" />
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
<TextBlock.ContextMenu>
<ContextMenu>
<!--<MenuItem Header="Details" Command="{Binding DropedElementCommand, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window}}"/>-->
<MenuItem Header="Details">
<i:Interaction.Triggers>
<!-- EventName ??? -->
<i:EventTrigger EventName="Click">
<i:InvokeCommandAction Command="{Binding Path=PlacementTarget.Tag.DataContext.MyCommand, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window}}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</MenuItem>
</ContextMenu>
</TextBlock.ContextMenu>
</TextBlock>
</StackPanel>
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
<i:Interaction.Triggers>
<i:EventTrigger EventName="SelectedItemChanged">
<i:InvokeCommandAction Command="{Binding SelectedUBRElementCommand}"
CommandParameter="{Binding SelectedItem, ElementName=tvUBR}" />
</i:EventTrigger>
</i:Interaction.Triggers>
<TreeView.ItemContainerStyle>
<Style TargetType="{x:Type TreeViewItem}">
<Setter Property="b:TreeViewItemBehavior.IsBroughtIntoViewWhenSelected" Value="True" />
<Setter Property="IsExpanded" Value="{Binding IsExpanded, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" />
<Setter Property="IsSelected" Value="{Binding IsSelected, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" />
</Style>
</TreeView.ItemContainerStyle>
</TreeView>
Any idea how to achieve this?
You could bind the Tag property of the TextBlock to the view model and then bind to the command using the PlacementTarget property of the ContextMenu:
<HierarchicalDataTemplate ItemsSource="{Binding Children}">
<StackPanel Orientation="Horizontal">
<TextBlock VerticalAlignment="Center" Text="{ Binding Description }">
<TextBlock.Style>
<Style TargetType="TextBlock">
<Setter Property="Tag" Value="{Binding DataContext, RelativeSource={RelativeSource AncestorType=TreeView}}" />
<Setter Property="Foreground" Value="Black" />
<Style.Triggers>
<DataTrigger Binding="{Binding IsMatch}" Value="True">
<Setter Property="Foreground" Value="Green" />
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
<TextBlock.ContextMenu>
<ContextMenu>
<MenuItem Header="Details"
Command="{Binding PlacementTarget.Tag.MyCommand, RelativeSource={RelativeSource AncestorType=ContextMenu}}" />
</ContextMenu>
</TextBlock.ContextMenu>
</TextBlock>
</StackPanel>
</HierarchicalDataTemplate>
How can I change HierarchicalDataTemplate by DataTrigger in my TreeView?
<TreeView Grid.Row="2" Grid.Column="1" Grid.ColumnSpan="2"
ItemsSource="{Binding Nodes}">
<TreeView.ItemContainerStyle>
<Style TargetType="TreeViewItem">
<Setter Property="IsExpanded" Value="True" />
</Style>
</TreeView.ItemContainerStyle>
<TreeView.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding Nodes}">
<HierarchicalDataTemplate.Triggers>
<DataTrigger Binding="{Binding Type}" Value="group">
<Setter Property="Content">
<Setter.Value>
<TextBlock Text="{Binding Title}" />
</Setter.Value>
</Setter>
</DataTrigger>
<DataTrigger Binding="{Binding Type}" Value="page">
<Setter Property="Content">
<Setter.Value>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Page.Name}" />
<TextBlock Text="{Binding Page.Format}" />
</StackPanel>
</Setter.Value>
</Setter>
</DataTrigger>
</HierarchicalDataTemplate.Triggers>
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
In ItemSource of TreeView i put list of Node objects:
public class Node
{
public string Title { get; set; }
public Page Page { get; set; }
public string Type { get; set; }
public List<Node> Nodes { get; set; } = new List<Node>();
}
And this is the result:
What am I doing wrong?
In WPF, the "correct" way to create complex content is with a template.
I tried the XAML below, and it worked. Where I bind Content="{Binding}" on the inner ContentControl, that just binds the content of the contentcontrol to the DataContext of the parent -- in this case, the Node object.
<TreeView
Grid.Row="2" Grid.Column="1" Grid.ColumnSpan="2"
ItemsSource="{Binding Nodes}"
>
<TreeView.ItemContainerStyle>
<Style TargetType="TreeViewItem">
<Setter Property="IsExpanded" Value="True" />
</Style>
</TreeView.ItemContainerStyle>
<TreeView.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding Nodes}">
<ContentControl
x:Name="PART_ContentControl"
Content="{Binding}"
/>
<HierarchicalDataTemplate.Triggers>
<DataTrigger Binding="{Binding Type}" Value="Group">
<Setter Property="ContentTemplate" TargetName="PART_ContentControl">
<Setter.Value>
<DataTemplate>
<TextBlock Text="{Binding Title}" />
</DataTemplate>
</Setter.Value>
</Setter>
</DataTrigger>
<DataTrigger Binding="{Binding Type}" Value="Page">
<Setter Property="ContentTemplate" TargetName="PART_ContentControl">
<Setter.Value>
<DataTemplate>
<StackPanel Orientation="Vertical">
<TextBlock Text="{Binding Page.Name}" />
<TextBlock Text="{Binding Page.Format}" />
</StackPanel>
</DataTemplate>
</Setter.Value>
</Setter>
</DataTrigger>
</HierarchicalDataTemplate.Triggers>
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
I have managed to create a datagrid that contains different type of control on same column. However, I am not able to get the user input in these controls.
Item
public class Item
{
/// <summary>
/// item name
/// </summary>
public string ParameterName { get; set; }
/// <summary>
/// Control type
/// </summary>
public ControlType ControlType { get; set; }
/// <summary>
/// New item value
/// </summary>
public object ParameterValue { get; set; }
/// <summary>
/// Current item value
/// </summary>
public string CurrentParameterValue { get; set; }
}
ControlType
public enum ControlType
{
TextBox,
ComboBox,
CheckBox,
TextBlock
}
DataGrid
<DataGrid x:Name="dgridGeneral" ItemsSource="{Binding}" AutoGenerateColumns="False" CanUserAddRows="False" CanUserResizeColumns="False" SelectionUnit="FullRow">
<DataGrid.Columns>
<DataGridTemplateColumn Header="Name" Width="200">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding ParameterName}" Style="{StaticResource TextHeader}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Header="New Value" Width="200">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ContentControl Content="{Binding}">
<ContentControl.Style>
<Style TargetType="ContentControl">
<Style.Triggers>
<DataTrigger Binding="{Binding ControlType}" Value="CheckBox">
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<CheckBox IsChecked="{Binding ParameterValue, Mode=TwoWay}"/>
</DataTemplate>
</Setter.Value>
</Setter>
</DataTrigger>
<DataTrigger Binding="{Binding ControlType}" Value="ComboBox">
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<ComboBox ItemsSource="{Binding ComboBoxControlItemSource}" SelectedIndex="{Binding ParameterValue, Mode=TwoWay}" />
</DataTemplate>
</Setter.Value>
</Setter>
</DataTrigger>
<DataTrigger Binding="{Binding ControlType}" Value="TextBlock">
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<TextBlock Text="{Binding ParameterValue}"/>
</DataTemplate>
</Setter.Value>
</Setter>
</DataTrigger>
<DataTrigger Binding="{Binding ControlType}" Value="TextBox">
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<TextBox Text="{Binding ParameterValue, Mode=TwoWay}" />
</DataTemplate>
</Setter.Value>
</Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</ContentControl.Style>
</ContentControl>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Header="Current Value" Width="*">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding CurrentParameterValue}" Style="{StaticResource TextBodyNormal}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
I have also tried to add additional properties for different control types in Item class. For instance, a "Text" property for TextBox, a "IsCheck" property for CheckBox, a SelectedIndex property for ComboBox. However, I still was not able to obtain the user input.
How do I obtain the inputs from the user?
The ParameterValue property of the Item will be set if you set the UpdateSourceTrigger property of the bindings to PropertyChanged:
<Style.Triggers>
<DataTrigger Binding="{Binding ControlType}" Value="CheckBox">
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<CheckBox Content="{Binding}" IsChecked="{Binding ParameterValue, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"/>
</DataTemplate>
</Setter.Value>
</Setter>
</DataTrigger>
<DataTrigger Binding="{Binding ControlType}" Value="ComboBox">
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<ComboBox ItemsSource="{Binding ComboBoxControlItemSource}"
SelectedIndex="{Binding ParameterValue, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
</DataTemplate>
</Setter.Value>
</Setter>
</DataTrigger>
<DataTrigger Binding="{Binding ControlType}" Value="TextBlock">
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<TextBlock Text="{Binding ParameterValue}"/>
</DataTemplate>
</Setter.Value>
</Setter>
</DataTrigger>
<DataTrigger Binding="{Binding ControlType}" Value="TextBox">
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<TextBox Text="{Binding ParameterValue, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" />
</DataTemplate>
</Setter.Value>
</Setter>
</DataTrigger>
</Style.Triggers>
Is there a way to hide items of a combobox in WPF?
In my usercontrol there is a ListBox with checkbox-items bound to an ObservableCollection and a datagrid with a combobox.
<ListBox x:Name="AvailableAttributes" Grid.Row="0" Grid.Column="2" SelectionMode="Single" >
<ListBox.ItemContainerStyle>
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="IsSelected" Value="{Binding IsSelected, Mode=OneWay}"/>
</Style>
</ListBox.ItemContainerStyle>
<ListBox.ItemTemplate>
<DataTemplate>
<CheckBox Content="{Binding Name}" IsChecked="{Binding IsSelected}"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
...
<DataGrid Name="datagrid" AutoGenerateColumns="False" >
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding Name}" />
<DataGridComboBoxColumn
SelectedValueBinding="{Binding CBID}"
DisplayMemberPath="Name"
SelectedValuePath="ID">
<DataGridComboBoxColumn.ElementStyle>
<Style TargetType="{x:Type ComboBox}">
<Setter Property="ItemsSource"
Value="{Binding Path=CBItems, RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}" />
</Style>
</DataGridComboBoxColumn.ElementStyle>
<DataGridComboBoxColumn.EditingElementStyle>
<Style TargetType="{x:Type ComboBox}">
<Setter Property="ItemsSource"
Value="{Binding Path=CBItems, RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}" />
</Style>
</DataGridComboBoxColumn.EditingElementStyle>
</DataGridComboBoxColumn>
</DataGrid.Columns>
</DataGrid>
I used this solution to manage the combobox items and added the property 'IsSelected'
public class GridItem
{
public string Name { get; set; }
public int CBID { get; set; }
}
public class CBItem
{
public int ID { get; set; }
public string Name { get; set; }
public bool IsSelected { get; set; }
}
Now I want to use the 'IsSelected' property to hide/show the item in the combobox. Can someone tell me how can I achieve this?
Pretty simple: Just give the combobox items a style with a trigger that sets ComboBoxItem.Visibility according to the value of IsSelected on the ComboBoxItem's DataContext:
<Style TargetType="{x:Type ComboBox}" BasedOn="{StaticResource {x:Type ComboBox}}">
<Setter Property="ItemsSource"
Value="{Binding Path=CBItems, RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}" />
<Setter Property="ItemContainerStyle">
<Setter.Value>
<Style TargetType="ComboBoxItem" BasedOn="{StaticResource {x:Type ComboBoxItem}}">
<Style.Triggers>
<DataTrigger Binding="{Binding IsSelected}" Value="False">
<Setter Property="Visibility" Value="Collapsed" />
</DataTrigger>
</Style.Triggers>
</Style>
</Setter.Value>
</Setter>
</Style>
If you might ever be updating the value of IsSelected on any of these items after the ComboBoxes are loaded in the grid, you will need to implement INotifyPropertyChanged on CBItem so that the UI will reflect the change.
If you wanna show a specific property and filter out items according to another property value you should use ItemTemplate and ItemContainerStyle together.
In this example ItemSource has set to an ObservableCollection type property which is part of another Combobox ItemSource
<ComboBox x:Name="combo2" ItemsSource="{Binding SelectedItem.Devices,ElementName=combo1}">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Name}"></TextBlock>
</DataTemplate>
</ComboBox.ItemTemplate>
<ComboBox.ItemContainerStyle>
<Style TargetType="ComboBoxItem">
<Style.Triggers>
<DataTrigger Binding="{Binding DeviceId}" Value="125">
<Setter Property="Visibility" Value="Collapsed"></Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</ComboBox.ItemContainerStyle>
</ComboBox>
I going crazy that I just can't change the color of the ComboBox. Have tried to use the background property right on the ComboBox but nothing happens.
Have also tried to use a Style block and set the background color, but that does also not work.
Code
<ComboBox Padding="7" Height="34" Background="#ffffff">
<ComboBox.Resources>
<Style x:Key="{x:Type ComboBox}" TargetType="ComboBox">
<Setter Property="Background" Value="red" />
<Setter Property="BorderThickness" Value="1" />
<Setter Property="BorderBrush" Value="black" />
</Style>
</ComboBox.Resources>
<ComboBoxItem IsSelected="True">1 - Room</ComboBoxItem>
<ComboBoxItem>2 - Rooms</ComboBoxItem>
<ComboBoxItem>3 - Rooms</ComboBoxItem>
<ComboBoxItem>4 - Rooms</ComboBoxItem>
<ComboBoxItem>5+ - Rooms</ComboBoxItem>
</ComboBox>
Even though that I have set the background color to white, It still only the standard grey color.
Here you can see how it looks:
Hope someone can tell me what I'm doing wrong?
here are several thing which in my opinion can help you:
Remove the Background definition from the ComboBox declaration(Background="#ffffff").
Move the combo items declaration to the combo holding Grid because of the fact that ItemTemplate and ItemTemplateSelector are ignored for items already of the ItemsControl's container.
Implement the data template selector to support data templates of combo (one for selected item, second for the items to select).
Here is the XAML code
<Grid>
<Grid.Resources>
<x:Array Type="{x:Type system:String}" x:Key="MyRoomsArray">
<system:String>1 - Room</system:String>
<system:String>2 - Rooms</system:String>
<system:String>3 - Rooms</system:String>
<system:String>4 - Rooms</system:String>
<system:String>5+ - Rooms</system:String>
</x:Array>
</Grid.Resources>
<ComboBox Padding="7" Height="34" SelectedIndex="0" ItemsSource="{StaticResource MyRoomsArray}">
<ComboBox.Resources>
<DataTemplate x:Key="ItemToSelect">
<Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<Border HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
Background="Red"
BorderBrush="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ComboBox}, Path=BorderBrush, UpdateSourceTrigger=PropertyChanged}"
BorderThickness ="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ComboBox}, Path=BorderThickness, UpdateSourceTrigger=PropertyChanged}">
<TextBlock HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Text="{Binding }" />
</Border>
</Grid>
</DataTemplate>
<DataTemplate x:Key="SelectedItem">
<Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<Border HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
Background="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ComboBox}, Path=Background, UpdateSourceTrigger=PropertyChanged}"
BorderBrush="Transparent"
BorderThickness ="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ComboBox}, Path=BorderThickness, UpdateSourceTrigger=PropertyChanged}">
<TextBlock HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Text="{Binding }" />
</Border>
</Grid>
</DataTemplate>
<wpfComboBAckground:ComboDataTemplateSelector x:Key="ComboDataTemplateSelector" Selected="{StaticResource SelectedItem}" ItemToSelect="{StaticResource ItemToSelect}"/>
<Style TargetType="ComboBox">
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
<Setter Property="VerticalContentAlignment" Value="Stretch"/>
<Setter Property="Background" Value="Red" />
<Setter Property="BorderThickness" Value="1" />
<Setter Property="BorderBrush" Value="Black" />
<Setter Property="ItemTemplateSelector" Value="{StaticResource ComboDataTemplateSelector}"/>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="Transparent"></Setter>
</Trigger>
<Trigger Property="IsMouseOver" Value="False">
<Setter Property="Background" Value="Red"></Setter>
</Trigger>
</Style.Triggers>
</Style>
</ComboBox.Resources>
</ComboBox>
</Grid>
Here is the data template selector
public class ComboDataTemplateSelector : DataTemplateSelector
{
public override DataTemplate SelectTemplate(object item, DependencyObject container)
{
var selected = false;
// container is the ContentPresenter
FrameworkElement fe = container as FrameworkElement;
if (fe == null) return ItemToSelect;
var cbo = fe.TemplatedParent as ComboBox;
if (cbo != null)
selected = true;
return selected ? Selected : ItemToSelect;
}
public DataTemplate Selected { get; set; }
public DataTemplate ItemToSelect { get; set; }
}
How it looks like:
Regards.