ToggleButton Checked Event Handling - c#

I have ToggleButtons that are dynamically created based on my datasource. I would like to have only one togglebutton checked at a time when a user clicks one. How can I accomplish this?
<UserControl.Resources>
<ItemsPanelTemplate x:Key="HorizontalMiniDrawerList">
<StackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
<DataTemplate x:Key="MiniDrawerRowTemplate">
<ToggleButton x:Name="_MiniDrawerButton" Width="60" Height="85" Style="{DynamicResource MiniDrawerButtonWhite}" Checked="_MiniDrawerButton_Checked" >
</ToggleButton>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding Width}" Value="3">
<Setter TargetName="_MiniDrawerButton" Property="Width" Value="185"/>
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
<DataTemplate x:Key="MiniDrawerListItemTemplate">
<ListBox SelectionMode="Multiple" Background="#00000000" BorderThickness="0" Width="500"
ItemsPanel="{StaticResource HorizontalMiniDrawerList}"
ItemTemplate="{StaticResource MiniDrawerRowTemplate}"
ItemsSource="{Binding Row}" >
</ListBox>
</DataTemplate>
</UserControl.Resources>
<Grid Background="{DynamicResource ListBackgroundColor}" >
<ListBox x:Name="_MiniDrawerRows" BorderThickness="0" Background="Transparent" Margin="107,84,225,217" ScrollViewer.HorizontalScrollBarVisibility="Disabled"
ItemsSource="{Binding Path=MiniDrawerRows, diagnostics:PresentationTraceSources.TraceLevel=High}"
ItemTemplate="{StaticResource MiniDrawerListItemTemplate}" >
</ListBox>
</Grid>
Update: Instead of using a togglebutton I used a radiobutton and changed the style of the radio button to look like a togglebutton.
<Style x:Key="MiniDrawerButtonWhiteRadioToToggleButton" BasedOn="{StaticResource {x:Type ToggleButton}}" TargetType="{x:Type RadioButton}">

I assume you mean "only one" instead of "only when". In that case you can use RadioButton (which is derived from ToggleButton) instead and set a GroupName on _MiniDrawerButton in your ItemTemplate. It looks like you are probably already using a custom ControlTemplate so you can use the same one for RadioButton by just changing the Style and ControlTemplate TargetTypes.

Related

DataTemplate Doesn't Apply

I am new to WPF and some help would be appreciated.
I got a resource Dictionary where I am trying to style a ListViewItem or ItemTemplate ListView's Property, But both ways have failed.
First way:
Dictionary
<Style TargetType="ListViewItem">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<StackPanel Orientation="Horizontal">
<Ellipse Height="45" Width="45" Fill="Gray"/>
<ContentPresenter/>
</StackPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
MainWindow
<ListView Grid.Row="1" Background="LightSkyBlue">
<ListViewItem>Text cannot be seen</ListViewItem>
</ListView>
"This one doesn't show any text"
Second Way:
Dictionary
<DataTemplate x:Key="LeftMenuButtons">
<StackPanel Orientation="Horizontal">
<Ellipse Height="45" Width="45" Fill="Gray"/>
<ContentPresenter/>
</StackPanel>
</DataTemplate>
MainWindow
<ListView ItemTemplate="{StaticResource LeftMenuButtons}" Grid.Row="1" >
<ListViewItem>No Effect for DataTemplate Only Text Appears</ListViewItem>
</ListView>
This Doesn't apply anything in DataTemplate.
If possible I would like to know what is going wrong in both two ways ... Thanks in advance.
First Way - Control Template
Please specify the TargetType of the control template explicity.
<ControlTemplate TargetType="{x:Type ListViewItem}">
You could also give the list view item style a name, so it is not applied on all items in your scope, but only to the target list view.
<Style x:Key="ListViewItemStyle"
TargetType="ListViewItem">
Make sure, that you assign the style to your target list view.
<ListView Grid.Row="1"
Background="LightSkyBlue"
ItemContainerStyle="{StaticResource ListViewItemStyle}">
Second Way - Data Template
First, data templates only work if your items are assigned via the ItemsSource property. If you directly assign ListViewItems to your list view, they will not be affected. You have to bind the ItemsSource to a collection. Second, you do not use a ContentPresenter in the data template, you bind to properties of the objects in the ItemsSource collection. In this example you would have a collection of strings that are assigned to the Text property of the TextBlock. Maybe this is beyond the scope of your question.
<ListView Grid.Row="1"
ItemsSource="{Binding StringCollection}"
ItemTemplate="{StaticResource LeftMenuButtons}"/>
<DataTemplate x:Key="LeftMenuButtons"
<StackPanel Orientation="Horizontal">
<Ellipse Height="45"
Width="45"
Fill="Gray"/>
<TextBlock Text="{Binding}"/>
</StackPanel>
</DataTemplate>
The code below works. You just forgot to write ControlTemplate TargetType.
<Style x:Key="ListViewItemStyle" TargetType="ListViewItem">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListViewItem}">
<StackPanel Orientation="Horizontal">
<Ellipse Height="45" Width="45" Fill="Gray"/>
<ContentPresenter/>
</StackPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

WPF - Tooltip content binded to a combobox selected item

I have a datagrid which has, in the head of every column a combobox. I want a tooltip to appear when hovering the combobox, to show the selected item value
<DataGrid HeadersVisibility="Column" Name="griglia" Grid.Row="2" ItemsSource="{Binding Path=Test}" AutoGenerateColumns="True" IsReadOnly="True" ScrollViewer.CanContentScroll="True" ScrollViewer.VerticalScrollBarVisibility="Visible" ScrollViewer.HorizontalScrollBarVisibility="Visible">
<DataGrid.ColumnHeaderStyle>
<Style TargetType="{x:Type DataGridColumnHeader}">
<Setter Property="ContentTemplate" >
<Setter.Value>
<DataTemplate DataType="DataGridColumnHeader">
<ComboBox ItemContainerStyle="{StaticResource SingleSelectionComboBoxItem}" DisplayMemberPath="Oggetto" Width="100" Height="20" ItemsSource="{Binding RelativeSource={RelativeSource AncestorType={x:Type DataGrid}},Path=DataContext.Selezione, UpdateSourceTrigger=LostFocus}" SelectionChanged="SingleSelectionComboBox_SelectionChanged"/>
</DataTemplate>
</Setter.Value>
</Setter>
<Setter Property="ToolTip">
<Setter.Value>
<ToolTip Content = "what should i put here????"/>
</Setter.Value>
</Setter>
</Style>
</DataGrid.ColumnHeaderStyle>
</DataGrid>
What should i put inside the content property of the tooltip? I already tried
Content = "{Binding RelativeSource={RelativeSource AncestorType={x:Type DataGridColumnHeader}},Path=DataContext.Tot.Oggetto}"
where Tot.Oggetto is a string containing the displayed item in the combobox but it doesn't work
EDIT: I tried already to set tooltip property fo the combobox like
ToolTip="{Binding Path=SelectedItem.ToolTip, RelativeSource={RelativeSource Self}}"
but it does not show any tooltip
Your first try is setting the Tooltip of the DataGridColumnHeader, but it seems you want to set the Tooltip of the ComboBox, right?
You can set the Tooltip of a ComboBox to show its selected value as follows:
<ComboBox ToolTip="{Binding RelativeSource={RelativeSource Self}, Path=SelectedValue}" ...>
RelativeSource={RelativeSource Self} is binding to the ComboBox itself. Then Path=SelectedValue specifies that you want to bind to the property SelectedValue of this ComboBox, instead of binding directly to itself.
So your code would then be: (I erased the code that was setting the Tooltip of the DataGridColumnHeader and modified the code for the ComboBox inside the DataTemplate)
<DataGrid HeadersVisibility="Column" Name="griglia" Grid.Row="2" ItemsSource="{Binding Path=Test}" AutoGenerateColumns="True" IsReadOnly="True" ScrollViewer.CanContentScroll="True" ScrollViewer.VerticalScrollBarVisibility="Visible" ScrollViewer.HorizontalScrollBarVisibility="Visible">
<DataGrid.ColumnHeaderStyle>
<Style TargetType="{x:Type DataGridColumnHeader}">
<Setter Property="ContentTemplate" >
<Setter.Value>
<DataTemplate DataType="DataGridColumnHeader">
<ComboBox ToolTip="{Binding RelativeSource={RelativeSource Self}, Path=SelectedValue}" ItemContainerStyle="{StaticResource SingleSelectionComboBoxItem}" DisplayMemberPath="Oggetto" Width="100" Height="20" ItemsSource="{Binding RelativeSource={RelativeSource AncestorType={x:Type DataGrid}},Path=DataContext.Selezione, UpdateSourceTrigger=LostFocus}" SelectionChanged="SingleSelectionComboBox_SelectionChanged"/>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
</DataGrid.ColumnHeaderStyle>
</DataGrid>

How to use trigger in datatemplate in WPF

How to change property Fill of icon of current selected element in checkbox depending on IsChecked property?
My resource dictionary:
<UserControl.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<!-- (...) -->
</ResourceDictionary.MergedDictionaries>
<DataTemplate x:Key="FooTemplate">
<Icons:ExIcon Fill="Red"
Width="12"
Height="Auto">
<!--
<Icons:ExIcon.Triggers>
<DataTrigger Binding="{Binding RelativeSource={???}}, Path=???}" Maybe here?
Value="???"/>
</Icons:ExIcon.Triggers>
-->
</Icons:ExIcon>
</DataTemplate>
<!-- (...) -->
<styles:IconSelector x:Key="IconSelector"
FooTemplate="{StaticResource FooTemplate}"
FooTemplateSSecond="{StaticResource FooTemaplteSecond}"/>
And listbox:
<ListBox ItemsSource="{Binding DataSources}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<!-- (...) -->
<CheckBox IsChecked="{Binding IsSelected, Mode=TwoWay}">
<CheckBox.Template>
<!-- (...) -->
<ContentControl Name="Icon"
Content="{Binding}"
ContentTemplateSelector="{StaticResource IconSelector}"
HorizontalAlignment="Right"
Grid.Column="1"/>
<!-- (...) -->
</CheckBox.Template>
</CheckBox>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Is it possible?
It's not completely clear to me how your CheckBox.Template looks like. Also the Icons:ExIcon Control is a mystery to me. Anyway here is a small working example. It uses a Rectangle instead of your ExIcon. But you can easily replace it ;-) I've bound directly to IsSelected via a DataTrigger instead of searching by ElementName or RelativeSource.
XAML:
<ListBox ItemsSource="{Binding}">
<ListBox.Resources>
<DataTemplate x:Key="template1">
<StackPanel Orientation="Horizontal">
<CheckBox IsChecked="{Binding Path=IsSelected}" />
<Rectangle Height="20"
Width="20">
<Rectangle.Style>
<Style TargetType="Rectangle">
<Setter Property="Fill"
Value="Blue" />
<Style.Triggers>
<DataTrigger Binding="{Binding Path=IsSelected}"
Value="True">
<Setter Property="Fill"
Value="Red" />
</DataTrigger>
</Style.Triggers>
</Style>
</Rectangle.Style>
</Rectangle>
</StackPanel>
</DataTemplate>
</ListBox.Resources>
<ListBox.ItemTemplate>
<DataTemplate>
<ContentControl ContentTemplate="{StaticResource template1}" Content="{Binding}">
</ContentControl>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
NOTE Content="{Binding}". This sets the DataContext of the ContentPresenter to the "actual" DataContext of the ListBoxItem. If you use VS2015 you can investigate this with the VisualTreeViewer otherwise you can use https://snoopwpf.codeplex.com/
You should also consider to rename IsSelectedto IsChecked. Noramlly you use the IsSelected property for indicating if the row is selected or not.

How to add ItemsSource to Combobox nested in ListBox Template from codebehind?

I have some problem with ComboBox nested in ListBox. I want to add the same ItemsSource(gained from database, adding from codebehind) to each of comboboxes created in ListBox, but don't know how. Any ideas how to do this?
</Window.Resources>
<Style x:Key="lbxKey" TargetType="ListBox">
<Setter Property="ItemsPanel">
<Setter.Value>
<ItemsPanelTemplate>
<StackPanel/>
</ItemsPanelTemplate>
</Setter.Value>
</Setter>
<Setter Property="ItemTemplate">
<Setter.Value>
<DataTemplate DataType="{x:Type Type1}">
<StackPanel Orientation="Horizontal" Width="Auto" HorizontalAlignment="Stretch">
<TextBlock TextTrimming="CharacterEllipsis" Width="200" Text="{Binding NAMETYPE1}" HorizontalAlignment="Left"></TextBlock>
<ComboBox HorizontalAlignment="Stretch" Tag="{Binding IDTYPE1}">
<ComboBox.ItemsSource>
<!-- no idea what should be here or even if this is needed -->
</ComboBox.ItemsSource>
<ComboBox.ItemTemplate>
<DataTemplate DataType="{x:Type Type2}">
<StackPanel Orientation="Horizontal" Width="100">
<TextBlock Text="{Binding NAMETYPE2}" TextTrimming="CharacterEllipsis"/>
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
</StackPanel>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
In codebehind:
lbxListbox.ItemsSource = observableCollectionFromDatabase;
//here should be sth to set ItemsSource for comboboxes in ListBox
There should be a collection type property in your item class (anything that implements IEnumerable will do). Then you would bind the ComboBox's ItemSource like this:
<ComboBox Tag="{Binding IDTYPE1}" ItemsSource="{Binding ITEMS}" ...>

ItemsControl with none background WPF

I would like to ask you, if is possible to have ItemsControl without background (x:null), not transparent.
I have collection with data, and these are showed in ItemsControl with help of DataTemplate. Some data in datatemplate are collapsed, and I need to be able to clickable on another control behind the itemscontrol.
Here is example what I mean:
<Button x:Name="bt_behind"></Button>
<ItemsControl ItemsSource="{Binding ListOfData}" Background="{x:Null}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" Background="{x:Null}"></StackPanel>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate DataType="{x:Type Class:Data}">
<Grid Width="100" Background="{x:Null}">
<Rectangle x:Name="rec" Fill="Red" Height="100" Visibility="Collapsed">
</Grid>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding IsVisible}" Value="true">
<Setter TargeName="rec" Property="Visibility" Value="Visible"/>
</DataTrigger>
<DataTemplate.Triggers>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
Example where item3 is partly collapsed and marked area, where is empty place
I set everywhere the background to null (try itemcontainerstyle too), but without success. On button behind ItemsControl still is not clickable. I think that ItemsControl have transparent background for events, but is it possible to remove this background?
Thanks for any advice and sorry for my english:)
-pav-
Well, as i said, it's all working. Fixed XAML:
<Grid>
<Button x:Name="bt_behind" Content="behind" Click="Bt_behind_OnClick"/>
<ItemsControl ItemsSource="{Binding ListOfData}" Background="{x:Null}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" Background="{x:Null}"></StackPanel>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate DataType="{x:Type local:Data}">
<Grid Width="100" Background="{x:Null}">
<Rectangle x:Name="rec" Fill="Red" Height="100" Visibility="Collapsed"/>
</Grid>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding IsVisible}" Value="true">
<Setter TargetName="rec" Property="Visibility" Value="Visible"/>
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
Just for test.
private void Bt_behind_OnClick(object sender, RoutedEventArgs e)
{
MessageBox.Show("");
}

Categories