ToggleButtons in WPF - c#

I have two ToggleButtons. I want only one of them to be in the Pressed state at any time. So let's say Model ToggleButton is pressed:
I want to achieve the below concepts:
If I press Drawing ToggleButton, the Model ToggleButton will be unpressed and Drawing ToggleButton will go to pressed state.
If press the Model Button which is in the pressed state nothing will happen.
By the way here is all I have done so far :(
<ToggleButton Width="50" Height="23" Margin="0 0 0 0">Model</ToggleButton>
<ToggleButton Width="50" Height="23" Margin="0 0 7 0">Drawing</ToggleButton>
Update:
Using the provided link under the comments, I came up with this:
<RadioButton Style="{StaticResource {x:Type ToggleButton}}" Content="Model" IsChecked="True" />
<RadioButton Style="{StaticResource {x:Type ToggleButton}}" Content="Drawing" />
Now the above code gives me two buttons, but how can I style these? I know how to style. But I don't know what to style here? I mean I have already filled the style property here how can I style the ToggleButton itself?

Since RadioButton inherits from ToggleButton, you can set ToggleButton style to it and use BasedOn to inherit default style of ToggleButton like this:
<RadioButton GroupName="Test" Width="50" Height="23" Margin="0 0 7 0"
Content="Model">
<RadioButton.Style>
<Style TargetType="ToggleButton"
BasedOn="{StaticResource {x:Type ToggleButton}}">
<Setter Property="Background" Value="Red"/>
<!-- Set other properties here-->
</Style>
</RadioButton.Style>
</RadioButton>

According to this answer that DLeh linked in comments, you can do this by styling a RadioButton to use the ToggleButton styles.
<RadioButton Style="{StaticResource {x:Type ToggleButton}}" />
To answer your second question on how to customize the style property for this, you can create another style that inherits from the base ToggleButton style, and use it instead. Like this:
<Style x:Key="CustomToggleButtonStyle"
TargetType="{x:Type RadioButton}"
BasedOn="{StaticResource {x:Type ToggleButton}}">
// Custom Style setters here
</Style>
<RadioButton Style="{StaticResource CustomToggleButtonStyle}" />
And of course there's always the option of completely rewriting the entire template yourself from scratch. MSDN has a good examples of a custom ToggleButton Template you could use to start with.

Related

Horizontal alignment in control seems to be ignored on all but the last item

I have a custom radio button based on togglebutton:
<Style TargetType="{x:Type local:ToolbarRadioButton}" BasedOn="{StaticResource {x:Type ToggleButton}}">
<Setter Property="Width" Value="60"/>
<Setter Property="Height" Value="60"/>
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<StackPanel Orientation="Vertical">
<iconPacks:PackIconModern Kind="{Binding TbIcon, RelativeSource={RelativeSource AncestorType=RadioButton}}"
Height="30" Width="35" HorizontalAlignment="Center"/>
<TextBlock Text="{Binding TbText, RelativeSource={RelativeSource AncestorType=RadioButton}}" FontSize="12"
HorizontalAlignment="Center"/>
</StackPanel>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
I use this control to create four toggle/radio buttons. I've horizontal centered the items in datatemplate, but I end up with this:
Forecast and its icon seem to be centered, but the others are partially left-aligned. They all use the same control so shouldn't they all be centered?
EDITS FOR CLARITY:
It doesn't matter which order I put them in, Forecast is always the one that's aligned correctly.
There is no whitespace in the text nor is there whitespace in the images and all images are sized according to the control defined above. Here's the implementation portion in case it's useful, though they're all the exact same:
<StackPanel Orientation="Horizontal" Grid.Column="0" Grid.Row="0">
<customs:ToolbarRadioButton TbText="Day" TbIcon="CalendarDay" GroupName="calViewType" x:Name="dayOnOff"/>
<customs:ToolbarRadioButton TbText="Week" TbIcon="CalendarWeek" GroupName="calViewType" x:Name="weekOnOff"/>
<customs:ToolbarRadioButton TbText="Month" TbIcon="CalendarMonth" GroupName="calViewType" x:Name="monthOnOff" IsChecked="True"/>
<customs:ToolbarRadioButton TbText="Forecast" TbIcon="PeopleMultiple" GroupName="calViewType" x:Name="forecastOnOff"/>
</StackPanel>
For future readers: I figured out the answer by digging into the documentation on Button. There is a property on buttons called HorizontalContentAlignment (and vertical, of course) that apparently needs to be set to align the visual content. You can't set the HorizontalAlignment property of the item that is the content explicitly; apparently, the button wants to do that for you.

How to change text in Toggle switch from NuGet?

I am using a Toggle switch that I downloaded from NuGet.
It has a standard "ON/OFF" text on the switch.
I was trying to change the text to say something else, is this possible through styles on XAML?
As #DavidPilkington mentioned, use the CheckedContent and UncheckedContent properties. They accept "content" just like a Button or any other ContentControl, meaning you can assign simple text to them:
<toggleSwitch:HorizontalToggleSwitch IsChecked="True" CheckedContent="Activated!" />
or anything inheriting from UIElement:
<toggleSwitch:HorizontalToggleSwitch>
<toggleSwitch:HorizontalToggleSwitch.UncheckedContent>
<StackPanel>
<Ellipse Height="40" Width="40" Fill="Blue"/>
<TextBlock TextAlignment="Center">Disabled</TextBlock>
</StackPanel>
</toggleSwitch:HorizontalToggleSwitch.UncheckedContent>
</toggleSwitch:HorizontalToggleSwitch>
Well it seems the answer was so simple I am really surprised,
<Style TargetType="{x:Type switch:HorizontalToggleSwitch}">
<Setter Property="CheckedContent" Value="RUN"/>
<Setter Property="UncheckedContent" Value="STOP"/>
</Style>
This changes the text value for each state.

A style gives rise to a different rendering result if given a x:Key

A style gives rise to a different rendering result if given a x:Key
I have the following Style and ControlTemplate for ToggleButtons and they work as I want it to.
<Style TargetType="RadioButton" BasedOn="{StaticResource {x:Type ToggleButton}}"/>
<ControlTemplate TargetType="RadioButton" x:Key="RadioTemplate">
<RadioButton IsChecked="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=IsChecked, Mode=TwoWay}">
<RadioButton.Content>
<Viewbox StretchDirection="DownOnly" Stretch="Uniform">
<ContentControl Content="{TemplateBinding Content}"/>
</Viewbox>
</RadioButton.Content>
</RadioButton>
</ControlTemplate>
However, when I give an x:Key to the Style and the RadioButton in the ControlTemplate inherits the Style as shown in the following,
the rendering result is different from the one given by the code above.
<Style TargetType="RadioButton" BasedOn="{StaticResource {x:Type ToggleButton}}" x:Key="RadioStyle"/>
<ControlTemplate TargetType="RadioButton" x:Key="RadioTemplate">
<RadioButton Style="{StaticResource RadioStyle}"
IsChecked="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=IsChecked, Mode=TwoWay}">
<RadioButton.Content>
<Viewbox StretchDirection="DownOnly" Stretch="Uniform">
<ContentControl Content="{TemplateBinding Content}"/>
</Viewbox>
</RadioButton.Content>
</RadioButton>
</ControlTemplate>
Could anyone tell me why this happens?
The MSDN documentation:
Setting the TargetType property to the RadioButton type without setting an x:Key implicitly sets the x:Key to {x:Type RadioButton }. This also means that if you give the above Style an x:Key value of anything other than {x:Type RadioButton}, the Style would not be applied to all RadioButton elements automatically. Instead, you need to apply the style to the RadioButton elements explicitly like "{StaticResource RadioStyle}".
You need to use the key when you specify one.
The Style with a key, will not get automatically reflected to the togglebuttons.

WPF: Style ToolTip with Image

Is it possible to create a style for ToolTip that would place an image next to the Item on which the tool tip resides and then show the tool tip text when the user hovers over the image? Something like this:
Currently I am doing a StackPanel to add the image with the tool tip like so:
<StackPanel Orientation="Horizontal">
<CheckBox Content="Reload Employee Data"
IsChecked="{Binding AdjustmentSettings.ReloadEmployeeData}"
Grid.Row="0"
Grid.Column="0">
</CheckBox>
<Image Source="/DelphiaLibrary;Component/Resources/info.ico"
ToolTip="Check if you want to re-upload ...."/>
</StackPanel>
EDIT
Just to clarify, I am looking for a way to style ToolTip such that if I define ToolTip on any object (i.e., Button, CheckBox, etc.) the info image is shown and the tool tip text is placed on this info image.
I would like to be able to do something like this and still get the same as the stack panel above:
<CheckBox Content="Reload Employee Data"
IsChecked="{Binding AdjustmentSettings.ReloadEmployeeData}"
Grid.Row="0"
Grid.Column="0"
ToolTip="Blah blah blah..."
Style="{StaticResource ToolTipImageStyle}">
</CheckBox>
And be able to apply this ToolTipImageStyle to any control (i.e., Button, CheckBox, TextBox, etc.). If that isn't possible can I style an individual control and just create different styles for different controls (one for buttons, another for TextBlock, etc.)?
This should do it. I couldn't figure out the color so just change that.
Source 1
Source 2
<Image Source="/DelphiaLibrary;Component/Resources/info.ico" Width="25" Height="25">
<Image.ToolTip>
<ToolTip Background="LightBlue">
<TextBlock Width="200" TextWrapping="WrapWithOverflow">
Check if you want to re-upload table foxpro.hrpersnl from the source. <LineBreak />
Leave unchecked to use existing data that has been previously uplaoded.
</TextBlock>
</ToolTip>
</Image.ToolTip>
</Image>
Update 1:
Source 1
In the App.xaml add this:
<Application.Resources>
<Style TargetType="{x:Type ToolTip}">
<Setter Property="OverridesDefaultStyle" Value="True" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ToolTip}" >
<TextBox Background="LightBlue" Width="200" TextWrapping="WrapWithOverflow" Text="{TemplateBinding ToolTip.Content}" />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Application.Resources>
Then in your XAML file change to:
Note: This will work with all object's tool tips.
<Image Source="Images/MenuImageZoomOut.png" Width="25" Height="25"
ToolTip="Check if you want to re-upload table foxpro.hrpersnl from the source. Leave unchecked to use existing data that has been previously uplaoded." />
The image:
If this doesn't work, try this: Source

Window with ListBox is not displaying error on the ListBox

I have a dialog in my WPF application which contains a ListBox. The ListBox uses the following DataTemplate to display its contents:
<DataTemplate x:Key="AlarmClassTemplate">
<CheckBox Content="{Binding Path=Value}"
IsChecked="{Binding IsChecked}" />
</DataTemplate>
I've also configured the following template and style to display when there is an error in the ListBox's contents:
<ControlTemplate x:Key="InputErrorTemplateA">
<DockPanel LastChildFill="True">
<Image DockPanel.Dock="Right"
Height="30"
Margin="5"
Source="{StaticResource ErrorImage}"
ToolTip="Contains invalid data"
VerticalAlignment="Center"
Width="30" />
<Border BorderBrush="Red"
BorderThickness="5"
Margin="5">
<AdornedElementPlaceholder />
</Border>
</DockPanel>
</ControlTemplate>
<Style TargetType="{x:Type ListBox}">
<Setter Property="Validation.ErrorTemplate" Value="{StaticResource InputErrorTemplateA}" />
<Style.Triggers>
<Trigger Property="Validation.HasError" Value="True">
<Setter Property="ToolTip">
<Setter.Value>
<Binding Path="(Validation.Errors).CurrentItem.ErrorContent" RelativeSource="{x:Static RelativeSource.Self}" />
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
</Style>
And here's the XAML for the ListBox itself:
<ListBox FontSize="20"
FontWeight="Bold"
Grid.Column="1"
Grid.ColumnSpan="2"
Grid.Row="1"
Height="158"
ItemsSource="{Binding Path=IDs, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True}"
ItemTemplate="{StaticResource AlarmClassTemplate}"
Margin="5,0,110,0"
Name="AlarmClassListBox"
ToolTip="{x:Static res:Car.EditDataRetention_AlarmClasses_ToolTip}"
Visibility="{Binding Converter={StaticResource BoolToVisibility}, Path=DataTypeIsAlarms}" />
The validation logic for the data in the ListBox is that at least one item has to be checked off. If none of them are, the ListBox should display an error and the OK button on the dialog should be disabled.
The good news is that the OK button on the dialog is indeed disabled when nothing in the ListBox is checked. The bad news is that the Style doesn't seem to be working, in that no red border is displayed around the ListBox and the error image (a red circle with a white exclamation point inside) does not show.
I'm using the same exact ControlTempate and a similar Style on other controls on the same dialog and they work fine. What am I doing wrong? Is it the ListBox? Does ListBox validation work differently?
Indeed the problem is you weren't raising PropertyChanged event for your validation to gets fired.
But i can see one more issue in your code. You have set local value for tooltip on ListBox here:
ToolTip="{x:Static res:Car.EditDataRetention_AlarmClasses_ToolTip}"
But you want different tooltip in case validation returns some error which you define in style triggers.
But, local value has higher precedence order than style triggers. So, your tooltip will never be set. So, you should move the tooltip to style setters to work:
<Setter Property="ToolTip"
Value="{x:Static res:Car.EditDataRetention_AlarmClasses_ToolTip}"/>
MSDN link - Dependency property value precedence.
I found the answer to my problem in this post. It turns out that I have to raise the PropertyChanged event when the checkboxes change in order for the Validation logic to fire. Since the items in the ListBox implement INotifyPropertyChanged, it was easy to add an event listener for each item as it's added to the ListBox which raises the necessary event.
Thanks anyway.

Categories

Resources