I have this ComboBox
<ComboBox x:Name="Renderer" ItemsSource="{Binding RendererItems}"
ItemTemplate="{StaticResource DropDownItemTemplate}" SelectedIndex="0">
<i:Interaction.Triggers>
<i:EventTrigger EventName="SelectionChanged">
<ei:CallMethodAction TargetObject="{Binding}"
MethodName="RendererItemsSelectionChanged"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</ComboBox>
And this Data Template for the items
<DataTemplate x:Key="DropDownItemTemplate">
<StackPanel Orientation="Horizontal">
<UserControl Content="{Binding Icon}" Width="24" Height="24"/>
<TextBlock Text="{Binding Text}" VerticalAlignment="Center" HorizontalAlignment="Left" Margin="10,0"/>
</StackPanel>
</DataTemplate>
And the data comes from:
public ObservableCollection<ComboBoxItemModel> RendererItems { get; set; } = new ObservableCollection<ComboBoxItemModel>();
public MainWindowViewModel()
{
RendererItems.Add(new ComboBoxItemModel() { Icon = new RenderedIcon(), Text = "Rendered" });
RendererItems.Add(new ComboBoxItemModel() { Icon = new WireframeIcon(), Text = "Wireframe" });
RendererItems.Add(new ComboBoxItemModel() { Icon = new ShadedIcon(), Text = "Shaded" });
RendererItems.Add(new ComboBoxItemModel() { Icon = new HiddenLinesIcon(), Text = "Hidden Lines" });
}
The ComboBoxItemModel class is defined like this:
public class ComboBoxItemModel
{
public UserControl Icon { get; set; }
public string Text { get; set; }
}
The first time that I click on the Combo is shown like this:
As you can see the selected item have no Icon
The second time that I click on the Combo is shown like this:
Now the item that I have selected have no Icon. But I want that Combo items always have an Icon.
CodePudding user response:
A UIElement - like your UserControl Icon
- can only have one parent element and can therefore only appear once in a visual tree. You should not have a UIElement at all as a view model data item.
In order to model an icon, use a bitmap or a drawing in a DrawingImage:
public class ComboBoxItemModel
{
public ImageSource Icon { get; set; } // assign a DrawingImage
public string Text { get; set; }
}
with
<DataTemplate x:Key="DropDownItemTemplate">
<StackPanel Orientation="Horizontal">
<Image Source="{Binding Icon}" Width="24" Height="24"/>
<TextBlock Text="{Binding Text}" .../>
</StackPanel>
</DataTemplate>
An alternative with a UserControl Icon might be to fill a Rectangle with a VisualBrush:
<DataTemplate x:Key="DropDownItemTemplate">
<StackPanel Orientation="Horizontal">
<Rectangle Width="24" Height="24">
<Rectangle.Fill>
<VisualBrush Visual="{Binding Icon}"/>
</Rectangle.Fill>
</Rectangle>
<TextBlock Text="{Binding Text}" .../>
</StackPanel>
</DataTemplate>