fire event only from user request - c#

Is the any way to make Checked and Unchecked only fire when button clicked by user?
IsChecked is bound to Playing property. This value may change from background (not by user). So it causes Checked and Unchecked events to fire again and conflict with other things.
When ever I try to write code to fix this it becomes real mess. Thanks for your help.
<ToggleButton x:Name="TogglePlay" Width="90"
Style="{DynamicResource TogglePlay}"
IsChecked="{Binding SessionData.Playing}"
Checked="TogglePlay_Checked" Unchecked="TogglePlay_OnUnchecked"/>
<StackPanel.Resources>
<Style x:Key="TogglePlay" TargetType="ToggleButton">
<Style.Triggers>
<DataTrigger Binding="{Binding IsChecked , ElementName=TogglePlay}" Value="False">
<Setter Property="Content" Value="Play" />
</DataTrigger>
<DataTrigger Binding="{Binding IsChecked , ElementName=TogglePlay}" Value="True">
<Setter Property="Content" Value="Pause" />
</DataTrigger>
</Style.Triggers>
</Style>
</StackPanel.Resources>

You can try to use binding mode "OneWayToSource"

Related

Conditional Tooltip Based On Checkbox WPF

I've got a checkbox and a button in my WPF MVVM app. If the checkbox is checked I want a tooltip on the button that says "x" and if it's unchecked the tooltip should say "y".
Anyone know the best way to do this? I think it could be done with a separate property in my view model, but maybe there's an easier way to do this in just the xaml?
Thanks in advance.
You could use a Style with a DataTrigger that binds to the IsChecked property of the CheckBox:
<CheckBox x:Name="chk" Content="CheckBox" />
<Button Content="Button">
<Button.Style>
<Style TargetType="Button">
<Setter Property="ToolTip" Value="y" />
<Style.Triggers>
<DataTrigger Binding="{Binding IsChecked, ElementName=chk}" Value="True">
<Setter Property="ToolTip" Value="x" />
</DataTrigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>

WPF:Using checkbox IsChecked property in DataTrigger

I am trying to use WPF checkbox's IsChecked property in a DataTrigger.Based on the value i am setting particular DataGridRow's background.
My NOT WORKING code
<Style TargetType="{x:Type DataGridRow}">
<Setter Property="Background" Value="LightGray" />
<Setter Property="SnapsToDevicePixels" Value="true"/>
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=chkbox, Path=IsChecked}" Value="true">
<Setter Property="Background" Value="LightCyan" />
</DataTrigger>
</Style.Triggers>
</Style>
<DataGrid x:Name="dataGrid1" AutoGenerateColumns="False">
<DataGrid.Columns>
<DataGridTemplateColumn MinWidth="40" Width="Auto" Header="Select">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<CheckBox x:Name="chkbox" IsChecked="{Binding Selected, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"></CheckBox>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
Then I checked this link and changed the code as below and it is working fine.Here Selected is my public property.
<Style TargetType="{x:Type DataGridRow}">
<Setter Property="Background" Value="LightGray" />
<Setter Property="SnapsToDevicePixels" Value="true"/>
<Style.Triggers>
<DataTrigger Binding="{Binding Selected}" Value="true">
<Setter Property="Background" Value="LightCyan" />
</DataTrigger>
</Style.Triggers>
</Style>
Please help me to understand why my original code is not working? am i missing anything.
google did not help.surprisingly there is no thread for this on SO also! Thank you for the help.
The original code is not working because you're trying to locate an object via ElementName which exists as a templated object, and thus isn't created until after the binding tries to resolve. Generally, you should only use ElementName when referring to ancestor objects in the visual tree, and not to children, particularly templated children.
As mentioned in comments, it would also not be possible to use a {RelativeSource FindAncestor... binding here because the CheckBox is a child, not an ancestor, of the DataGridRow

Validation on DataGrid

I have a datagrid displaying ObservableCollection in my xaml. One of my validation rule on one of the columns is "Name cannot be blank" when the Name field is blank. It all works fine.
My problem is that when my Name field validation is triggered (if name was blank), the Name field is outlined with red box. Imagine at this stage the user fills in a name but the red box still remains even if you click on the other fields of the same row. The red box goes away only when the user clicks on a different row. Is there any way to make the red box disappear when the user click on different fields of the same row?
My xaml for the Name field is
<Window.Resources>
<Style x:Key="EditCellStyleError" TargetType="{x:Type TextBox}">
<Style.Triggers>
<Trigger Property="Validation.HasError" Value="true">
<Setter Property="ToolTip" Value="{Binding RelativeSource={RelativeSource Self}, Path=(Validation.Errors)[0].ErrorContent}"/>
</Trigger>
</Style.Triggers>
</Style>
<Style x:Key="CellStyleError" TargetType="{x:Type TextBlock}">
<Style.Triggers>
<Trigger Property="Validation.HasError" Value="true">
<Setter Property="ToolTip" Value="{Binding RelativeSource={RelativeSource Self}, Path=(Validation.Errors)[0].ErrorContent}"/>
</Trigger>
</Style.Triggers>
</Style>
</Window.Resources>
The Name field
<DataGridTextColumn Header="Name" Binding="{Binding Name,ValidatesOnDataErrors=True, NotifyOnValidationError=True, ValidatesOnExceptions=True}" EditingElementStyle="{StaticResource EditCellStyleError}" ElementStyle="{StaticResource CellStyleError}"/>
I think you need to add UpdateSourceTrigger to your binding
eg
<DataGridTextColumn Header="Name"
Binding="{Binding Name,ValidatesOnDataErrors=True, NotifyOnValidationError=True,
ValidatesOnExceptions=True, UpdateSourceTrigger=LostFocus}" />
here Ive used LostFocus but PropertyChanged might be an option
UpdateSourceTrigger=PropertyChanged definitely helped. Another problem was to get rid of red exclamation mark. To achieve this I added a blank Rowvalidationtemplate
<DataGrid.RowValidationErrorTemplate>
<ControlTemplate>
</ControlTemplate>
</DataGrid.RowValidationErrorTemplate>

One setting is determined by the second settings

I have the same options in different WPF dialog. One option that depends on another. If I click on the first, I also want to check the second. Both options correspond to the private bool variable in different classes. What is the best solution for this problem?
You could do that in WPF/XAML with Style.Triggers. For example the following code is an example on how to bind a textblock control's IsEnabled status based on the status of a checkbox (checked/unchecked)
<TextBlock Text="mytextblockText: ">
<TextBlock.Style>
<Style TargetType="TextBlock">
<Style.Triggers>
<DataTrigger Binding="{Binding IsChecked,ElementName=myCheckbox}" Value="False">
<Setter Property="IsEnabled" Value="True"/>
</DataTrigger>
<DataTrigger Binding="{Binding IsChecked, ElementName=myCheckbox}" Value="True">
<Setter Property="IsEnabled" Value="False"/>
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
For a checkbox being checked when another checkbox is checked, it looks like this (I guess)
<CheckBox>
<CheckBox.Style>
<Style TargetType="CheckBox">
<Style.Triggers>
<DataTrigger Binding="{Binding IsChecked,ElementName=myCheckbox}" Value="False">
<Setter Property="IsChecked" Value="True"/>
</DataTrigger>
<DataTrigger Binding="{Binding IsChecked, ElementName=myCheckbox}" Value="True">
<Setter Property="IsChecked" Value="False"/>
</DataTrigger>
</Style.Triggers>
</Style>
</CheckBox.Style>
</CheckBox>
*edit
can the properties in the classes be changed by something different than by those checkboxes? If yes, you could fire an event when the property is changed or directly manipulate the checkstate of the according box. Also, are the boxes dependent on each other? Or is just one dependent on the other (A <=> B or A => B)?
For manipulating the properties when one of the boxe's state is changed you could use the Checked/Unchecked events. Or use DependencyProperty as described in Pat's answere over here

Change property depending on property in other control - WPF

I want to use some kind of trigger to change a button in my window to IsEnabled = False when the textbox property Validation.HasErrors of my textbox is True.
Can I do this with Triggers of some kind on the Button?
If yes, some example would be nice!
You can do this by using a Style. If you want to tie it directly to the text box, you could do something like this:
<Style x:Key="DisabledOnErrors" TargetType="{x:Type Button}">
<Style.Triggers>
<DataTrigger Binding="{Binding (Validation.HasErrors)}" Value="True">
<Setter Property="IsEnabled" Value="False"/>
</DataTrigger>
</Style.Triggers>
</Style>
<TextBox x:Name="myTextBox" />
<Button Style="{StaticResource DisabledOnErrors}"
DataContext="{Binding ElementName=myTextBox}" />
This works if the button is not already binding to the DataContext for other properties. In this case, the Style is reusable for other button and text box pairings.
Yes, you can do this with triggers, but because you are referring to another element, you must use a DataTrigger rather than a normal Trigger:
<Button>
<Button.Style>
<Style TargetType="Button">
<Style.Triggers>
<DataTrigger Binding="{Binding (Validation.HasError), ElementName=tb}" Value="True">
<Setter Property="IsEnabled" Value="False" />
</DataTrigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
Note you must use a Style rather than the Button.Triggers collection, because Button.Triggers can contain only EventTriggers.

Categories