Unable to command bind toggle button as control template - wpf

Here is the code :
<Window.DataContext>
<local:MainWindowViewModel />
</Window.DataContext>
<Window.Resources>
<Style x:Key="RadioToggleButtonStyle" TargetType="RadioButton">
<Setter Property="SnapsToDevicePixels" Value="true" />
<Setter Property="OverridesDefaultStyle" Value="true" />
<Setter Property="Background" Value="Transparent" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type RadioButton}">
<ToggleButton Content="{Binding Content, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay}" IsChecked="{Binding IsChecked, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay}" />
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="Width" Value="150" />
<Setter Property="Height" Value="25" />
<Setter Property="VerticalAlignment" Value="Center" />
</Style>
</Window.Resources>
<Grid>
<RadioButton Name="radioButton1"
Height="29"
Margin="193,195,0,0"
HorizontalAlignment="Left"
VerticalAlignment="Top"
**Command="{Binding Path=RadioClickCommand}"**
Content="RadioButton"
Style="{StaticResource RadioToggleButtonStyle}" />
</Grid>
In MainWindowViewModel : I have following command registration
public ICommand RadioClickCommand
{
get { return new RelayCommand(RadioClickExecute); }
}
private void RadioClickExecute()
{
}
Button click never triggers the command bind.
any help would be appreciated.

You forgot in your style that you have to define a Command of a ToggleButton
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type RadioButton}">
<ToggleButton Content="{Binding Content, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay}" IsChecked="{Binding IsChecked, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay}"
Command="{Binding Command, RelativeSource={RelativeSource TemplatedParent}, Mode=OneWay}"/>
</ControlTemplate>
</Setter.Value>
</Setter>

Related

StaticResource alters border of TextBox

I needed a placeholder for TextBox and found this working code:
<Style x:Key="placeHolder" TargetType="{x:Type TextBox}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TextBox}">
<Grid>
<TextBox Text="{Binding Path=Text,
RelativeSource={RelativeSource TemplatedParent},
Mode=TwoWay,
UpdateSourceTrigger=PropertyChanged}"
x:Name="textSource"
Background="Transparent"
Panel.ZIndex="2"
BorderThickness="0,0,0,1"/>
<TextBox Text="{TemplateBinding Tag}" Background="{TemplateBinding Background}" Panel.ZIndex="1">
<TextBox.Style>
<Style TargetType="{x:Type TextBox}">
<Setter Property="Foreground" Value="Transparent"/>
<Style.Triggers>
<DataTrigger Binding="{Binding Path=Text, Source={x:Reference textSource}}" Value="">
<Setter Property="Foreground" Value="LightGray"/>
</DataTrigger>
</Style.Triggers>
</Style>
</TextBox.Style>
</TextBox>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
This is my TextBox:
<TextBox x:Name="isci_tb" HorizontalAlignment="Left" Height="25" Margin="0,0,0,0" TextWrapping="Wrap"
VerticalAlignment="Center" Width="120" BorderThickness="0, 0, 0, 1" TextChanged="isci_tb_TextChanged" Tag="išči" Style="{StaticResource placeHolder}">
<TextBox.Background>
<ImageBrush/>
</TextBox.Background>
</TextBox>
Since I am new to XAML I don't see where or what changes the border of my button. I wish to only have the bottom border but instead all 4 borders are shown.
Set the BorderThickness property of the inner TextBox in your template to 0:
<Style x:Key="placeHolder" TargetType="{x:Type TextBox}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TextBox}">
<Grid>
<TextBox Text="{Binding Path=Text,
RelativeSource={RelativeSource TemplatedParent},
Mode=TwoWay,
UpdateSourceTrigger=PropertyChanged}"
x:Name="textSource"
Background="Transparent"
Panel.ZIndex="2"
BorderThickness="0,0,0,1"/>
<TextBox Text="{TemplateBinding Tag}" Background="{TemplateBinding Background}" Panel.ZIndex="1"
BorderThickness="0">
<TextBox.Style>
<Style TargetType="{x:Type TextBox}">
<Setter Property="Foreground" Value="Transparent"/>
<Style.Triggers>
<DataTrigger Binding="{Binding Path=Text, Source={x:Reference textSource}}" Value="">
<Setter Property="Foreground" Value="LightGray"/>
</DataTrigger>
</Style.Triggers>
</Style>
</TextBox.Style>
</TextBox>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

How to bind a property of external control?

I've a ToggleButton control that I've inserted in my Grid in this way:
xmlns:LSControls="clr-namespace:LS"
and then:
<LSControls:Favourite />
What I need to do is bind the IsSelected property of each item of ListView, infact I've inserted the control inside a ListView like this:
<ListView x:Name="AllMatches" ItemsSource="{Binding Source={StaticResource GroupedItems}}" SelectionChanged="AllMatches_SelectionChanged">
<ListView.View>
<GridView AllowsColumnReorder="False">
<GridViewColumn>
<GridViewColumn.CellTemplate>
<DataTemplate>
<LSControls:Favourite />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
this will display the control in eac item of my ListView, but I need to check or uncheck the ToggleButton based on the value of IsSelected, this property is available for each item of AllMatches source.
How can do this?
The structure of the control is like this:
<UserControl.Resources>
<BitmapImage x:Key="Star" UriSource="add-favourite.png" />
<BitmapImage x:Key="StarEmpty" UriSource="add-favourite-empty.png" />
</UserControl.Resources>
<Grid x:Name="LayoutRoot" Background="Transparent">
<ToggleButton Focusable="False" Width="19" Height="19">
<ToggleButton.Style>
<Style TargetType="{x:Type ToggleButton}">
<Setter Property="HorizontalContentAlignment" Value="Center"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ToggleButton}">
<Border>
<ContentPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
RecognizesAccessKey="True"
HorizontalAlignment="Center"/>
</Border>
<ControlTemplate.Triggers>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding = "{Binding RelativeSource={RelativeSource Mode=Self}, Path=IsChecked}" Value="False" />
<Condition Binding = "{Binding RelativeSource={RelativeSource Mode=Self}, Path=IsEnabled}" Value="True" />
</MultiDataTrigger.Conditions>
<Setter Property="Content">
<Setter.Value>
<Image Source="{StaticResource StarEmpty}"/>
</Setter.Value>
</Setter>
<Setter Property="ToolTip" Value="Add to favourite."/>
</MultiDataTrigger>
<Trigger Property="IsChecked" Value="True">
<Setter Property="Content">
<Setter.Value>
<Image Source="{StaticResource Star}"/>
</Setter.Value>
</Setter>
<Setter Property="ToolTip" Value="Remove from Favourite."/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ToggleButton.Style>
</ToggleButton>
</Grid>

How to change foreground of SelectedItem in ListBox?

I have asked this question yesterday and got a good quick answer. But now I have something different where the last solution does not work.
First lets have a look at my xaml:
<ListBox ItemsSource="{Binding Children}" x:Name="lst">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel IsItemsHost="True" Orientation="Vertical" MaxHeight="{Binding ElementName=lst, Path=ActualHeight}"/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.Resources>
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="Width" Value="250" />
<Setter Property="Height" Value="125" />
<Setter Property="Margin" Value="2.5" />
<Setter Property="Padding" Value="2.5" />
<Setter Property="Background" Value="{Binding Background, Converter={StaticResource stringToBrushConverter}}" />
<Setter Property="Foreground" Value="White" />
<Setter Property="VerticalContentAlignment" Value="Bottom" />
</Style>
</ListBox.Resources>
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" Height="125" Width="250">
<Path Data="{Binding Image}" VerticalAlignment="Center"
Stretch="Uniform" Fill="#FFFFFFFF"
Width="68" Height="68" Margin="10" RenderTransformOrigin="0.5,0.5">
<Path.RenderTransform>
<TransformGroup>
<TransformGroup.Children>
<RotateTransform Angle="0" />
<ScaleTransform ScaleX="1" ScaleY="1" />
</TransformGroup.Children>
</TransformGroup>
</Path.RenderTransform>
</Path>
<TextBlock Text="{Binding Title, Converter={StaticResource spaceToNewLineConverter}}" VerticalAlignment="Top"
Margin="40,10,10,10" FontSize="24" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
The above xaml works perfectly well and gives good output. But now I want to change the foreground color of SelectedItem.
Here you can find find the question that I asked yesterday.
Now, the solution to the question asked yesterday was something like this :
<Style x:Key="BlankListBoxContainerStyle" TargetType="{x:Type ListBoxItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}" />
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="FocusVisualStyle" Value="{x:Null} "/>
</Style>
If I change the template as shown in the above code I loose my DataTemplate that I applied on the listbox.
I have also tried SolidColorBrush and using Setters and Triggers. But I am out of luck.
You can do this by using a trigger in your Style. Try something like this:
<ListBox.Resources>
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="Width" Value="250" />
<Setter Property="Height" Value="125" />
<Setter Property="Margin" Value="2.5" />
<Setter Property="Padding" Value="2.5" />
<Setter Property="Background" Value="{Binding Background, Converter={StaticResource stringToBrushConverter}}" />
<Setter Property="Foreground" Value="White" />
<Setter Property="VerticalContentAlignment" Value="Bottom" />
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Foreground" Value="Red" />
</Trigger>
</Style.Triggers>
</Style>
</ListBox.Resources>
In this case, you need to pass Foreground value in the DataTemplate of ListBoxItem. This can be done as follows:
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal"
Height="125"
Width="250">
...
<TextBlock Foreground="{Binding Path=Foreground,
RelativeSource={RelativeSource AncestorType={x:Type ListBoxItem}}}" ... />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>

WPF style triggers on a TreeView?

I have the following treeview defined in my xaml:
<TreeView Name="PST_TreeView"
Grid.Row="0"
Grid.Column="0"
Width="Auto"
Height="Auto"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
ItemsSource="{Binding SitesCollection}"
ItemTemplate="{StaticResource SitesTemplate}"
Style="{StaticResource TreeViewStyleBasic}" />
With Resource bindings targeting my resources file:
<Style x:Key="TreeViewStyleBasic" TargetType="TreeView">
<Setter Property="Background" Value="Transparent" />
<Setter Property="BorderBrush" Value="{DynamicResource TitleBarButtons_BorderBrush}" />
<Setter Property="BorderThickness" Value="0 0 2 0" />
</Style>
<Style x:Key="TreeViewItemStyle_CatNodes" TargetType="{x:Type TextBlock}">
<Setter Property="Foreground" Value="Snow" />
<Setter Property="FontFamily" Value="Calibri" />
<Setter Property="FontSize" Value="16" />
<Setter Property="FontWeight" Value="Normal" />
<Setter Property="TextAlignment" Value="Left" />
</Style>
<Style x:Key="TreeViewItemStyle_ChildNodes" TargetType="{x:Type TextBlock}">
<Setter Property="Foreground" Value="Snow" />
<Setter Property="FontFamily" Value="Calibri" />
<Setter Property="FontSize" Value="14" />
<Setter Property="FontWeight" Value="Normal" />
<Setter Property="FontStyle" Value="Italic" />
<Setter Property="TextAlignment" Value="Left" />
</Style>
<DataTemplate x:Key="VolumeInfoDataTemplate">
<StackPanel Orientation="Horizontal">
<TextBlock Width="{TemplateBinding Width}"
Height="{TemplateBinding Height}"
Margin="5"
Style="{DynamicResource TreeViewItemStyle_ChildNodes}"
Text="{Binding VolumeName}" />
</StackPanel>
</DataTemplate>
<HierarchicalDataTemplate x:Key="SitesTemplate"
ItemsSource="{Binding VolumesList}"
ItemTemplate="{StaticResource VolumeInfoDataTemplate}">
<StackPanel Orientation="Horizontal">
<TextBlock Width="{TemplateBinding Width}"
Height="{TemplateBinding Height}"
Margin="5"
Style="{DynamicResource TreeViewItemStyle_CatNodes}"
Text="{Binding SiteName}" />
</StackPanel>
</HierarchicalDataTemplate>
The xaml and resource look ups above work find and as expected.
How might I employ triggers to extend my style definitions to say for example handle the 'IsSelected' event so that the selected tree node will have a slate grey border and a light grey background?
RESEARCH: Kind of thing I am going for.
UPDATE: There is no IsSelected property on the TreeView, however TreeViewItem does has one defined.
Try this:
<DataTemplate x:Key="VolumeInfoDataTemplate">
<StackPanel Orientation="Horizontal">
<TextBlock Width="{TemplateBinding Width}"
Height="{TemplateBinding Height}"
Margin="5"
Style="{DynamicResource TreeViewItemStyle_ChildNodes}"
Text="{Binding VolumeName}"
Name="Tb" />
</StackPanel>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding IsSelected, RelativeSource={RelativeSource AncestorType=TreeViewItem}}" Value="True">
<Setter TargetName="Tb" Property="Background" Value="LightGray"/>
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>

Listbox item style - how to show items in two rows..?

i have some listbox, which has this applied style:
<Style x:Key="GroupListBoxItemStyle"
TargetType="ListBoxItem">
<Setter Property="OverridesDefaultStyle"
Value="True" />
<Setter Property="FocusVisualStyle"
Value="{x:Null}" />
<Setter Property="FontSize"
Value="11" />
<Setter Property="FontWeight"
Value="Bold" />
<Setter Property="Width"
Value="95" />
<Setter Property="HorizontalAlignment"
Value="Center" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBoxItem">
<SlidingBar:SlidingBarRadioButton GroupName="PermissionsRadioButtonGroup"
IsChecked="{Binding Path=IsSelected,RelativeSource={RelativeSource TemplatedParent},BindsDirectlyToSource=True,Mode=TwoWay}"
Text="{Binding Converter={StaticResource resourceStringToResourceConverter}}"
ImageSource="{Binding Converter={StaticResource PermissionTypeToImageConverter}}"
Margin="1"
/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Is there possible to show somehow these items in two rows?
You should do this in the ListBox ItemTemplate property. The XAML looks something like this:
<ListBox Width="300" ItemsSource="{Binding}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding Line1}" />
<TextBlock Text="{Binding Line2}" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
The resulting listbox should look like:
Of course you don't have to use a StackPanel, you can use whatever kind of layout you like in the data template. Be creative :)

Resources