Set the area of influence of checkbox click - wpf

I am using the following code to create single click checkbox in a wpf DataGrid.
<DataGridTemplateColumn Header="Select">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<CheckBox Margin="16,3,0,0" IsChecked="{Binding IsSelected, UpdateSourceTrigger=PropertyChanged}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
This is the example
output:
The checkbox is selected only if user clicks to the right of the checkbox. If the user clicks to the left of the checkbox, it is not selected. How to fix this? I want the checkbox to be selected if the user clicks anywhere on the cell where the checkbox is located.

Create a custom template for the CheckBox or you could put it into a ToggleButton:
<DataGridTemplateColumn Header="Select">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ToggleButton Margin="0" IsChecked="{Binding IsSelected, UpdateSourceTrigger=PropertyChanged}">
<ToggleButton.Template>
<ControlTemplate TargetType="ToggleButton">
<Grid Background="Transparent">
<ContentPresenter />
</Grid>
</ControlTemplate>
</ToggleButton.Template>
<CheckBox Margin="16,3,0,0" IsChecked="{Binding IsChecked,
RelativeSource={RelativeSource AncestorType=ToggleButton}}" />
</ToggleButton>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>

You could "just" make the checkbox bigger.
<DataGridTemplateColumn Header="Select">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Viewbox>
<CheckBox IsChecked="{Binding IsSelected, Mode=TwoWay}" />
</Viewbox>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
Or use something isn't a checkbox at all if selection of row drives it.
Eg
<DataGridTemplateColumn Header="Select">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Rectangle>
<Rectangle.Fill>
<VisualBrush>
<VisualBrush.Visual>
<Grid>
<Path Fill="Green" Data="{StaticResource Tick}">
<Path.Style>
<Style TargetType="Path">
<Style.Triggers>
<DataTrigger Binding="{Binding IsSelected, RelativeSource={RelativeSource AncestorType=DataGridRow}}" Value="False">
<Setter Property="Visibility" Value="Collapsed"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Path.Style>
</Path>
<Path Fill="Red" Data="{StaticResource Cross}">
<Path.Style>
<Style TargetType="Path">
<Style.Triggers>
<DataTrigger Binding="{Binding IsSelected, RelativeSource={RelativeSource AncestorType=DataGridRow}}" Value="True">
<Setter Property="Visibility" Value="Collapsed"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Path.Style>
</Path>
</Grid>
</VisualBrush.Visual>
</VisualBrush>
</Rectangle.Fill>
</Rectangle>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
Tick and cross are a bit big but:
<Geometry x:Key="Tick">
M393.75,47.25L395.75,57.5 377.31640625,78.138671875 359.265625,98.8046875 341.59765625,119.498046875 324.3125,140.21875 307.41015625,160.966796875 290.890625,181.7421875 274.75390625,202.544921875 259,223.375 243.703125,244.130859375 228.9375,264.7109375 214.703125,285.115234375 201,305.34375 187.828125,325.396484375 175.1875,345.2734375 163.078125,364.974609375 151.5,384.5 149.53125,387.984375 147.375,391.9375 145.03125,396.359375 142.5,401.25 138.32421875,407.9296875 133.546875,413.71875 128.16796875,418.6171875 122.187492370605,422.625 115.60546875,425.7421875 108.421875,427.96875 100.63671875,429.3046875 92.25,429.75 84.90625,429.5703125 78.875,429.03125 74.15625,428.1328125 70.75,426.875 67.984375,424.9140625 65.1874923706055,421.90625 62.3593711853027,417.8515625 59.4999961853027,412.75 53.1093711853027,399.0390625 47.1875,384.40625 41.734375,368.8515625 36.75,352.375 34.5234375,344.220703125 32.59375,336.6953125 30.9609375,329.798828125 29.625,323.53125 28.5859375,317.892578125 27.84375,312.8828125 27.3984375,308.501953125 27.25,304.75 27.40625,301.203125 27.875,298.0625 28.65625,295.328125 29.75,293 31.3281230926514,290.796875 33.5625,288.4375 36.453125,285.921875 40,283.25 50.34375,277.09375 61.8749961853027,272.125 67.7109298706055,270.2109375 73.0937423706055,268.84375 78.0234375,268.0234375 82.5,267.75 84.296875,268.171875 86.1875,269.4375 88.171875,271.546875 90.25,274.5 92.421875,278.296875 94.6875,282.9375 97.046875,288.421875 99.5,294.75 100.374992370605,297.125 101,298.75 101.437492370605,300.125 102.25,302.25 104.515625,308.34375 106.6875,313.625 108.765625,318.09375 110.75,321.75 112.640625,324.59375 114.4375,326.625 116.140625,327.84375 117.75,328.25 118.52880859375,328.02001953125 119.552734375,327.330078125 120.82177734375,326.18017578125 122.335929870605,324.5703125 124.095207214355,322.50048828125 126.099601745605,319.970703125 128.34912109375,316.98095703125 130.84375,313.53125 133.58349609375,309.62158203125 136.568359375,305.251953125 139.79833984375,300.42236328125 143.2734375,295.1328125 146.99365234375,289.38330078125 150.958984375,283.173828125 155.16943359375,276.50439453125 159.625,269.375 178.0078125,240.3828125 196.53125,212.28125 215.1953125,185.0703125 234,158.75 246.789047241211,141.4765625 258.90625,125.65625 270.3515625,111.2890625 281.125,98.375 286.162109375,92.572265625 290.8359375,87.3515625 295.146484375,82.712890625 299.09375,78.65625 302.677734375,75.1816482543945 305.8984375,72.2890701293945 308.755859375,69.978515625 311.25,68.25 318.4921875,64.5156326293945 326.71875,61.0625114440918 335.9296875,57.8906364440918 346.125,55 357.1171875,52.4531288146973 368.71875,50.3125038146973 380.9296875,48.578125 393.75,47.25z
</Geometry>
<Geometry x:Key="Cross">
M361,24.25L365,33.7500038146973 376.75,50.25 360.5,70.5 342.8359375,92.4687576293945 326.34375,113.250015258789 311.0234375,132.843765258789 296.875,151.250015258789 283.8984375,168.468765258789 272.09375,184.500015258789 261.4609375,199.34375 252,213 318.5,359 310.25,366.25 310.25,372.25 297,382.5 300.5,392.75 295.96875,398.90625 290.375,403.875 287.3984375,405.7890625 284.59375,407.15625 281.9609375,407.9765625 279.5,408.25 277.634765625,407.84375 275.4140625,406.625 272.837890625,404.59375 269.90625,401.75 266.619140625,398.09375 262.9765625,393.625 258.978515625,388.34375 254.625,382.25 249.744140625,375.0859375 244.1640625,366.59375 237.884765625,356.7734375 230.90625,345.625 223.228515625,333.1484375 214.8515625,319.34375 205.775390625,304.2109375 196,287.75 180.84375,308.7109375 165.625,330.59375 150.34375,353.3984375 135,377.125 119.546867370605,401.8515625 103.937492370605,427.65625 88.171875,454.5390625 72.25,482.5 61.5,487 33.75,490 20.0000019073486,471 15.2499990463257,456.75 20.0000019073486,436.75 13.2500028610229,426.5 18.1953144073486,416.65234375 23.53125,406.609375 29.2578125,396.37109375 35.375,385.9375 41.8828125,375.30859375 48.7812461853027,364.484375 56.0703086853027,353.46484375 63.7499961853027,342.25 72.125,330.4296875 81.5,317.59375 91.875,303.7421875 103.25,288.875 115.625,272.9921875 129,256.09375 143.375,238.1796875 158.75,219.25 106,69.25 108.234375,64.2578201293945 110.4375,60.0312576293945 112.609375,56.5703201293945 114.75,53.875 116.921875,51.8515701293945 119.1875,50.4062576293945 121.546875,49.5390625 124,49.2499961853027 126.093742370605,49.5937538146973 128.375,50.625 131.03125,52.4687614440918 134.25,55.25 140.75,50.25 145.5,52.7500038146973 155.75,41.4999961853027 166,45.2499961853027 217,148 320,27.2499980926514 330.75,27.75 345.5,37.9999961853027 361,24.25z
</Geometry>

Related

How to set GridViewColumn Cell Template with Style Triggers

At the moment my grid is changing to Autogenerate columns so I cannot predefine the column style. I'm wondering how abouts do I set a style trigger for a column based on header value.
Working code with predefined columns with AutoGenerateColumns="True"
<telerik:GridViewColumn Header="Test">
<telerik:GridViewColumn.CellEditTemplate>
<DataTemplate x:Key="ToggleDataTemplate">
<telerik:RadToggleButton Content="+" Width="20" Height="20"
HorizontalContentAlignment="Center"
VerticalContentAlignment="Center"/>
</DataTemplate>
</telerik:GridViewColumn.CellEditTemplate>
</telerik:GridViewColumn>
What I've tried with AutoGenerateColumns="False"
<telerik:RadGridView.Resources>
<Style TargetType="telerik:GridViewColumn">
<Style.Triggers>
<Trigger Property="Header" Value="Test">
<Setter Property="CellTemplate" Value="{StaticResource ToggleDataTemplate}" />
<Setter Property="CellEditTemplate" Value="{StaticResource ToggleDataTemplate}" />
</Trigger>
</Style.Triggers>
</Style>
</telerik:RadGridView.Resources>
<DataTemplate x:Key="ToggleDataTemplate">
<telerik:RadToggleButton Content="+" Width="20" Height="20"
HorizontalContentAlignment="Center"
VerticalContentAlignment="Center"/>
</DataTemplate>
With what I tried above, the cell remains blank. How abouts do I get the button to appear dynamically?
You should be able to handle the AutoGeneratingColumn event and set the CellEditTemplate of all columns programmatically:
<telerik:RadGridView x:Name="grid" AutoGeneratingColumn="grid_AutoGeneratingColumn">
<telerik:RadGridView.Resources>
<DataTemplate x:Key="ToggleDataTemplate">
<telerik:RadToggleButton Content="+" Width="20" Height="20"
HorizontalContentAlignment="Center"
VerticalContentAlignment="Center"/>
</DataTemplate>
</telerik:RadGridView.Resources>
</telerik:RadGridView>
private void grid_AutoGeneratingColumn(object sender, Telerik.Windows.Controls.GridViewAutoGeneratingColumnEventArgs e)
{
e.Column.CellEditTemplate = grid.Resources["ToggleDataTemplate"] as DataTemplate;
}

WPF Binding to a RadioButton GroupName

I have a dynamic ListView using a DataTemplate as follows:
<ListView.ItemTemplate>
<DataTemplate>
<Border BorderThickness="0,0,0,1" BorderBrush="#ccc">
<RadioButton GroupName="MyRadioButtonGroup">
<StackPanel Orientation="Horizontal" Margin="0,0,0,5" Width="{Binding ActualWidth, ElementName=CheckoutGrid}">
<TextBlock Text="{Binding Path=Test1, StringFormat='{}{0} - '}" />
<TextBlock Text="{Binding Path=Test2, StringFormat='{} test {0} - '}" />
<TextBlock Text="{Binding Path=Test, StringFormat='{} test {0}'}" />
</StackPanel>
</RadioButton>
</Border>
</DataTemplate>
</ListView.ItemTemplate>
I would like to have a button disabled until one of the RadioButton IsChecked:
<RadioButton Padding="15,10" VerticalAlignment="Center">
<RadioButton.Style>
<Style TargetType="RadioButton" BasedOn="{StaticResource styleToggleButton4}">
<Setter Property="Visibility" Value="Collapsed" />
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=MyRadioButtonGroup, Path=IsChecked}" Value="False">
<Setter Property="IsEnabled" Value="False" />
</DataTrigger>
</Style.Triggers>
</Style>
</RadioButton.Style>
<TextBlock FontWeight="SemiBold" FontSize="14" Margin="0">NEXT</TextBlock>
</RadioButton>
So the problem is I do not know how to properly bind to the RadioButton GroupName="MyRadioButtonGroup". You will see in the DataTrigger above I am trying Binding="{Binding ElementName=MyRadioButtonGroup, Path=IsChecked}" Value="False", but that is not working for me since obviously it is a GroupName and not an x:Name.
Any suggestions on how to approach this properly? I would rather want to handle this on the front-end if at all possible.
You could bind your radio button to a command and then use the isChecked as a parameter. Then bind to a boolean value based off that. I think this may be more of a workaround though.
<RadioButton
Command="{Binding MyCommand}"
CommandParameter="{Binding RelativeSource={RelativeSource Self}, Path=IsChecked}"
GroupName="radio" />
<RadioButton
Command="{Binding MyCommand}"
CommandParameter="{Binding RelativeSource={RelativeSource Self}, Path=IsChecked}"
GroupName="radio" />
Then in code behind or VM, it would require implementing the ICommand Interface and INotifyPropertyChanged
public bool IsChecked
{
get { return isChecked;}
set
{
isChecked = value;
OnPropertyChanged();
}
}
private void OnMyCommand(object obj)
{
if(obj is bool)
{
IsChecked = (bool)obj;
}
}
A group has no IsChecked property that you can bind to.
If you don't have a source property that keeps track of whether there is at least one checked RadioButton and "want to handle this on the front-end" - which I guess means in the view - you could write some code that simply sets the Tag property of the ListView to true/false depending on whether there is a RadioButton selected. It is a one-liner:
private void ListView_Checked(object sender, RoutedEventArgs e) => lv.Tag = true;
<ListView x:Name="lv" ToggleButton.Checked="ListView_Checked">
<ListView.ItemTemplate>
...
<ListView.ItemTemplate>
</ListView>
<RadioButton Padding="15,10" VerticalAlignment="Center">
<RadioButton.Style>
<Style TargetType="RadioButton" BasedOn="{StaticResource styleToggleButton4}">
<Setter Property="Visibility" Value="Collapsed" />
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=lv, Path=Tag}" Value="True">
<Setter Property="Visibility" Value="Visible" />
</DataTrigger>
</Style.Triggers>
</Style>
</RadioButton.Style>
<TextBlock FontWeight="SemiBold" FontSize="14" Margin="0">NEXT</TextBlock>
</RadioButton>

How do you set WPF Hyperlink text via XAML

I have a button that has its content (text) set dynamically via a style against a backing property as below.
<Button>
<Button.Style>
<Style>
<Setter Property="Button.Content" Value="Advanced Search" />
<Style.Triggers>
<DataTrigger Binding="{Binding Path=IsAdvancedSearch}" Value="True">
<Setter Property="Button.Content" Value="Standard Search" />
</DataTrigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
I need to change this button to display just a hyperlink with the same dynamic text. Like this:
<Button>
<Button.Template>
<ControlTemplate>
<TextBlock>
<Hyperlink>
Standard Search
</Hyperlink>
</TextBlock>
</ControlTemplate>
</Button.Template>
</Button>
Is there a way to set the hyperlink's text (inline or some other tag) dynamically via a style still?
I haven't been able to get access to it via XAML. I got it working with a normal binding on a textblock inside the hyperlink but that is creating a redundant property on the viewmodel really.
You can embed another TextBlock inside your Hyperlink and bind it:
<TextBlock>
<Hyperlink>
<TextBlock Text="{Binding LinkText}" />
</Hyperlink>
</TextBlock>
Solution was to simply apply the style to an inner Textblock.
<Button x:Name="SwitchSearchType">
<Button.Template>
<ControlTemplate>
<TextBlock>
<Hyperlink>
<Hyperlink.Inlines>
<TextBlock>
<TextBlock.Style>
<Style>
<Setter Property="TextBlock.Text" Value="Advanced Search" />
<Style.Triggers>
<DataTrigger Binding="{Binding Path=IsAdvancedSearch}" Value="True">
<Setter Property="TextBlock.Text" Value="Standard Search" />
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
</Hyperlink.Inlines>
</Hyperlink>
</TextBlock>
</ControlTemplate>
</Button.Template>
</Button>
<GridViewColumn Header="{x:Static lang:Lang.wName}" CellTemplate="{StaticResource Template_DebitAccount}" />
And use into skin file
<DataTemplate x:Key="Template_DebitAccount">
<Border Padding="3" >
<TextBlock Text="{Binding wDebitAccountName}" Style="{StaticResource TextStyle_Path}">
<TextBlock.InputBindings>
<MouseBinding MouseAction="LeftClick" Command="{Binding DataContext.Base_PopPageCommand , RelativeSource={RelativeSource AncestorType=ListView}}" >
<MouseBinding.CommandParameter>
<MultiBinding Converter="{StaticResource MultiValueBindingConverter}">
<Binding Source="AgentSummary" />
<Binding Path="Link_Text"/>
</MultiBinding>
</MouseBinding.CommandParameter>
</MouseBinding>
</TextBlock.InputBindings>
</TextBlock>
</Border>
</DataTemplate>
Given:
<Hyperlink x:Name="uriEmailAddress" Click="Hyperlink_Click"></Hyperlink>
Code:
string e = Properties.Settings.Default.Email;
uriEmailAddress.NavigateUri = new Uri("mailto:" + e);
InlineCollection ic = uriEmailAddress.Inlines;
ic.Add(new Run(e));

WPF Xceed datagrid - datatrigger on cell's content makes me lose data on load...however re

I am using the Xceed datagrid for WPF. Today I was trying to change the background of the whole row if one of its column "SA" has the some value or not null. I wrote the following piece of code in XAML with a converter function in code behind:
<xcdg:DataGridControl.Resources>
<Style TargetType="{x:Type xcdg:DataRow}">
<Style.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Converter={StaticResource newConverter}, Path=Cells[SA].Content}" Value="True">
<Setter Property="Background" Value="LightGreen" />
</DataTrigger>
</Style.Triggers>
</Style>
</xcdg:DataGridControl.Resources>
To my surprise, as soon as I load the grid for the first time, the data in the SA column is nowhere to be seen. However, once I scroll down a bit, till the point that row which is supposed to have data for the column is not visible, and then when I scroll up again to see that row, I can see the value in that column as well as the background changed.
What am I doing wrong?
Use simple binding and avoid converter/template
<TextBlock Text="{Binding}"></TextBlock>
To fill color in your column use this or the following code:
<xcdg:Column Title="Unit Price" FieldName="UnitPrice" ReadOnly="True">
<xcdg:Column.CellContentTemplate>
<DataTemplate>
<DockPanel LastChildFill="false" x:Name="UnitPrice">
<TextBlock Text="{Binding}"></TextBlock>
<Image x:Name="img" Width="16" Height="16" DockPanel.Dock="Right"
Margin="2,0,0,0" Visibility="Collapsed"
ToolTip="Unit Price is Undefined." VerticalAlignment="Center"
HorizontalAlignment="Left" />
</DockPanel>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding}" Value="0.00">
<Setter TargetName="img" Property="Visibility" Value="Visible" />
<Setter TargetName="UnitPrice" Property="Background" Value="Pink" />
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</xcdg:Column.CellContentTemplate>
</xcdg:Column>

Calling a datatrigger for a radio button inside a datagrid

I have a datagrid with one column having a radio button. I want to set the GroupName when a certain condition is reached. Below is the code
<Custom:DataGrid.Columns>
<!-- ONLY ENABLED WHEN THE ITEM TYPE IS SINGLESELECT OR SINGLESELECT WITH ADDIOTIONAL DATA-->
<Custom:DataGridTemplateColumn CanUserResize="False" MinWidth="20" >
<Custom:DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<RadioButton IsChecked="{Binding IsChecked}" d:DesignWidth="16" d:DesignHeight="16" GroupName="SingleChoiceSelection" Template="{DynamicResource RadioButtonTemplate}" Background="{DynamicResource BackgroundNew}" BorderBrush="#FF7A7171" Foreground="#FF6C6C6C" Margin="0" />
</DataTemplate>
</Custom:DataGridTemplateColumn.CellTemplate>
</Custom:DataGridTemplateColumn>
<Custom:DataGridTextColumn Header="Choices" Binding="{Binding ChoiceText}" CellStyle="{DynamicResource DataGridCellStyle2}" MinWidth="150" />
</Custom:DataGrid.Columns>
</Custom:DataGrid>
The ItemSource contains a property called isChecked and I want to change the foreground color when isChecked is changed to true. How do i do this with a datatrigger?
<DataTrigger Binding="{Binding IsChecked}" Value="True" >
<Setter Property="Foreground" Value="Yellow" />
<DataTrigger>

Resources