Are any controls or kind of, with selectedindexchanged event or property selecteditem maybe?
I use ContentPresenter now and me need some solution for getting index of selected item issue. With DataTemplate inside, it's desirable.
My code looks:
<Border BorderThickness="1">
<ContentPresenter Content="{Binding Path=Value}">
<ContentPresenter.Resources>
<DataTemplate DataType="{x:Type System:String}">
<TextBox Text="{Binding Path=Content, RelativeSource={RelativeSource AncestorType={x:Type ContentPresenter}}}"
TextAlignment="Left"
BorderThickness="0"/>
</DataTemplate>
<DataTemplate DataType="{x:Type System:Int32}">
<TextBox Text="{Binding Path=Content, RelativeSource={RelativeSource AncestorType={x:Type ContentPresenter}}}"
TextAlignment="Left"
BorderThickness="0"/>
</DataTemplate>
<DataTemplate DataType="{x:Type System:Double}">
<TextBox Text="{Binding Path=Content, RelativeSource={RelativeSource AncestorType={x:Type ContentPresenter}}}"
TextAlignment="Left"
BorderThickness="0"/>
</DataTemplate>
<DataTemplate DataType="{x:Type System:Boolean}">
<Border Background="White">
<CheckBox IsChecked="{Binding Path=Content, RelativeSource={RelativeSource AncestorType={x:Type ContentPresenter}}}"
HorizontalAlignment="Left"/>
</Border>
</DataTemplate>
</ContentPresenter.Resources>
</ContentPresenter>
</Border>
You need an ItemsControl or its derivates ListView, ListBox, DataGrid etc. They have SelectedItem property on them.
In order to set the ItemTemplate depending on the any criteria, use DataTemplateSelector and set Itemscontrol.Itemtemplateselector property. Details at msdn
http://msdn.microsoft.com/en-us/library/system.windows.controls.itemscontrol.itemtemplateselector(v=vs.110).aspx
Related
I have a ComboBoxthat I have templated to look like this:
Here is the XAML for this ComboBox:
<ComboBox Name="StateInclusionRules_ComboBox"
ItemsSource="{Binding StateInclusionRules}"
Height="25"
Width="155"
Margin="0"
Grid.Column="7">
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal"
Margin="0">
<Label Content="{Binding State}"
Margin="0,0,0,0"
Width="30" />
<CheckBox IsChecked="{Binding StateTax}"
Margin="20,0,0,0"/>
<CheckBox IsChecked="{Binding StateChildSupport}"
Margin="30,0,0,0"/>
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
Is there a way to prevent the selected item from being displayed in the ComboBox ContentPresenter (the red bordered area, i.e, the area you see when the ComboBox is closed)?
First you need 2 DataTemplates, 1 for the selected item and 1 for the drop down item.
The selected we are going to leave empty because this is your requirment.
The drop down item DataTemplate will have the exact DataTemplate you wanted.
When item is selected a DataTrigger will change it's template to the SelectedTemplate, like so:
<Window.Resources>
<DataTemplate x:Key="DropDownItemTemplate" DataType="wpfApplication1:ItemSourceModel">
<StackPanel Orientation="Horizontal"
Margin="0">
<Label Content="{Binding Value}"
Margin="0,0,0,0"
Width="30" />
<CheckBox IsChecked="{Binding Value}"
Margin="20,0,0,0"/>
<CheckBox IsChecked="{Binding Value}"
Margin="30,0,0,0"/>
</StackPanel>
</DataTemplate>
<DataTemplate x:Key="SelectionBoxTemplate">
</DataTemplate>
<DataTemplate x:Key="ComboBoxTemplate">
<ContentPresenter x:Name="Presenter"
Content="{Binding}"
ContentTemplate="{StaticResource DropDownItemTemplate}" />
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource FindAncestor,ComboBoxItem,1}}" Value="{x:Null}">
<Setter TargetName="Presenter" Property="ContentTemplate" Value="{StaticResource SelectionBoxTemplate}" />
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</Window.Resources>
And set your ComboBox with the ComboBoxTemplate:
<ComboBox Name="StateInclusionRules_ComboBox"
ItemsSource="{Binding YourItemSource}" ItemTemplate="{StaticResource ComboBoxTemplate}"
Height="25"
Width="155"
Margin="0"
/>
I am trying to update the Combo ToolTip at the same time as the ComboItems.
<ComboBox x:Name="comboMeetingWeek" ItemsSource="{Binding Meetings}"
SelectedItem="{Binding Meeting, UpdateSourceTrigger=PropertyChanged}">
<ComboBox.ToolTip>
<ToolTip DataContext="{Binding Path=PlacementTarget, RelativeSource={RelativeSource Self}}"
Content="{Binding Path=SelectedItem.ToolTipForSpecialEvent}">
</ToolTip>
</ComboBox.ToolTip>
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" ToolTip="{Binding ToolTipForSpecialEvent}">
<Image Source="Images/Bell.png" Margin="0,0,5,0"
Visibility="{Binding DisplayBellImage, Converter={StaticResource BoolToHiddenConverter}}" Stretch="None"/>
<TextBlock Text="{Binding DateMeetingAsText}" />
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
The ComboBoxItems will always be correct. The but the ComboBox ToolTip won't.
OK, I found the solution. I had to do it like this:
<ComboBox x:Name="comboMeetingWeek" ItemsSource="{Binding Meetings}"
SelectedItem="{Binding Meeting, UpdateSourceTrigger=PropertyChanged}"
ToolTip="{Binding Meeting.ToolTipForSpecialEvent}">
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" ToolTip="{Binding ToolTipForSpecialEvent}">
<Image Source="Images/Bell.png" Margin="0,0,5,0"
Visibility="{Binding DisplayBellImage, Converter={StaticResource BoolToHiddenConverter}}" Stretch="None"/>
<TextBlock Text="{Binding DateMeetingAsText}" />
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
Less code ... even better .. :) But now is always works right.
This link helped.
I have the following DataTemplate used in a TreeView.
How do I have LeftMouseClick on the ContentPresenter to bind to a property of the DataType in MVVM fashion?
Thanks for any help (or better idea).
<DataTemplate x:Key="sharedTemplate">
<StackPanel Orientation="Horizontal">
<CheckBox
Focusable="False"
IsChecked="{Binding IsChecked}"
VerticalAlignment="Center"
/>
<ContentPresenter
Content="{Binding Name, Mode=OneTime}"
Margin="2,0"
/>
</StackPanel>
</DataTemplate>
<TreeView
ItemContainerStyle="{StaticResource TreeViewItemStyle}"
ItemsSource="{Binding ReportTree}" >
<TreeView.Resources>
<HierarchicalDataTemplate
DataType="{x:Type r:ReportViewModel}"
ItemsSource="{Binding Children}"
>
<ContentControl Content="{Binding}"
ContentTemplate="{StaticResource sharedTemplate}" />
</HierarchicalDataTemplate>
................
Addendum: This works!
<DataTemplate DataType="{x:Type r:PrinterViewModel}">
<!--Bind the ContentControl to the DataType-->
<ContentControl Content="{Binding}"
ContentTemplate="{StaticResource sharedTemplate}" >
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseDoubleClick">
<h:EventToCommand
Command="{Binding DataContext.SelectItem, RelativeSource={RelativeSource FindAncestor, AncestorType=TreeView}}"
CommandParameter="{Binding}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</ContentControl>
</DataTemplate>
Addendum: As it turns out, the above Interaction.Trigger does work to correctly send the selected viewmodel back to the DataContext of the TreeView. Problem solved.
How to display context menu for tree view item in wpf using the hierarchical data template? How to display context menu only for CountryTemplate:
<HierarchicalDataTemplate x:Key="DispTemplate">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Path=Label}" Style="{StaticResource TreeTextStyle}" ToolTip="{Binding Path=Description}" Tag="{Binding Path=Tag}">
</TextBlock>
</StackPanel>
</HierarchicalDataTemplate>
<HierarchicalDataTemplate x:Key="BuildingTemplate" ItemsSource="{Binding Path=Building}" ItemTemplate="{StaticResource BuildingTemplate}">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Path=Label}" Style="{StaticResource TreeTextStyle}" ToolTip="{Binding Path=Description}"/>
</StackPanel>
</HierarchicalDataTemplate>
<HierarchicalDataTemplate x:Key="CityTemplate" ItemsSource="{Binding Path=City}" ItemTemplate="{StaticResource CityTemplate}">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Path=Label}" Style="{StaticResource TreeTextStyle}" ToolTip="{Binding Path=Description}"/>
</StackPanel>
</HierarchicalDataTemplate>
<HierarchicalDataTemplate x:Key="CountryTemplate" ItemsSource="{Binding Path=Country}" ItemTemplate="{StaticResource CountryTemplate}">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Path=RootName}" Style="{StaticResource TreeTextStyle}" ToolTip="{Binding Path=Description}"/>
</StackPanel>
</HierarchicalDataTemplate>
You also can add the ContextMenu to any visual child in the data template, for instance:
<HierarchicalDataTemplate x:Key="CountryTemplate" ItemsSource="{Binding Path=Country}" ItemTemplate="{StaticResource CountryTemplate}">
<StackPanel Orientation="Horizontal">
<StackPanel.ContextMenu>
<ContextMenu>
<MenuItem Header="Header" Command="{Binding Command}"/> <!--This command should be in the data context (each country item)-->
</ContextMenu>
</StackPanel.ContextMenu>
<TextBlock Text="{Binding Path=RootName}" Style="{StaticResource TreeTextStyle}" ToolTip="{Binding Path=Description}"/>
</StackPanel>
</HierarchicalDataTemplate>
One of the reasons why context menus do not work as cleanly as they could is because by default, they are in a different visual tree to everything else, so the DataContext cannot be found.
The key insight is to create a <Style> that defines a context menu,
then attach that style to a target element, which hooks up the context
menu. This shifts the context menu into a visual tree that is lined up with the default DataContext you want.
First, create the style:
<UserControl.Resources>
<ResourceDictionary>
<!-- For the context menu to work, we must shift it into a style, which means that the context menu is now in a
visual tree that is more closely related to the current data context. All we have to do then is set the style,
which hooks up the context menu. -->
<Style x:Key="ContextMenuStyle" TargetType="{x:Type StackPanel}">
<Setter Property="ContextMenu" Value="{DynamicResource TreeViewContextMenu}"/>
</Style>
<ContextMenu x:Key="TreeViewContextMenu">
<MenuItem Header="Test" Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}, Path=DataContext.CmdDisplayDetailsGraph}"/>
</ContextMenu>
Then, hook the context menu up anywhere you want, without running into issues caused by different visual trees.
Example 1:
<HierarchicalDataTemplate DataType="{x:Type snapshot:Details}" ItemsSource="{Binding DetailsList}">
<StackPanel Orientation="Vertical" Style="{StaticResource ContextMenuStyle}">
<ContentPresenter Content="{Binding}" ContentTemplate="{Binding View.DefaultDataRowTemplate}" />
</StackPanel>
Example 2:
<DataTemplate DataType="{x:Type snapshot:InstrumentDetails}">
<StackPanel Orientation="Vertical" Style="{StaticResource ContextMenuStyle}">
<Grid HorizontalAlignment="Stretch" VerticalAlignment="Center">
<HierarchicalDataTemplate x:Key="CountryTemplate" ItemsSource="{Binding Path=Country}" ItemContainerStyle="{StaticResource CountryTemplateItemContainerStyle}" ItemTemplate="{StaticResource CountryTemplate}">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Path=RootName}" Style="{StaticResource TreeTextStyle}" ToolTip="{Binding Path=Description}" />
</StackPanel>
</HierarchicalDataTemplate>
<Style x:Key="CountryTemplateItemContainerStyle" TargetType="{x:Type TreeViewItem}">
<Setter Property="ContextMenu" Value="{DynamicResource TreeViewContextMenu}"/>
</Style>
<ContextMenu x:Key="TreeViewContextMenu">
<MenuItem .../>
</ContextMenu>
As you can see, you can add your contextmenu in the Itemcontainerstyle of the HierarchicalDataTemplate
Basically I came up with this
<HierarchicalDataTemplate x:Key="ChildTemplate">
<StackPanel Orientation="Horizontal">
<StackPanel.ContextMenu>
<ContextMenu>
<MenuItem Header="Copy" CommandParameter="{Binding CopyTag}">
</MenuItem>
<MenuItem Header="Paste" CommandParameter="{Binding PasteTag}">
</MenuItem>
<ContextMenu.ItemContainerStyle>
<Style TargetType="MenuItem">
<Setter Property="Command" Value="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}, Path=DataContext.CopyPaste}"/>
</Style>
</ContextMenu.ItemContainerStyle>
</ContextMenu>
</StackPanel.ContextMenu>
<Image Source="/Images/Child.png" Stretch="None" VerticalAlignment="Center" HorizontalAlignment="Center" Style="{StaticResource TreeIconStyle}"/>
<TextBlock Text="{Binding Path=Label}" Style="{StaticResource TreeTextStyle}" ToolTip="{Binding Path=Description}" Tag="{Binding Path=Tag}">
</TextBlock>
</StackPanel>
</HierarchicalDataTemplate>
And have separate parameters for copy and paste to differentiate copy and paste in a single command.
I have next code:
<ListBox Grid.Column="1" Grid.Row="4" Grid.RowSpan="2" Margin="0,0,1,0" MinHeight="80" Name="lbThemes" SelectionMode="Multiple" IsEnabled="True">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<CheckBox x:Name="ThemeCheckbox" />
<TextBlock Text="{Binding Path=label, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
I want to bind my checkbox in dataTemplate to the ListBoxItem IsSelected property. Any idea how can I do this?
P.S. I have use Multiple Selesction mode
Try the following
<CheckBox x:Name="ThemeCheckbox" IsChecked="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type ListBoxItem}},Path=IsSelected}" />