MVVM DataTrigger don't work - c#

I have the following code
<DockPanel.Style>
<Style TargetType="DockPanel">
<Setter Property="Visibility" Value="Hidden"/>
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=flowTreeView, Path=SelectedItem.hasInput}" Value="1" >
<Setter Property="Visibility" Value="Visible"/>
<Setter Property="FocusManager.FocusedElement" Value="{Binding ElementName=txtBoxPopUp}"/>
</DataTrigger>
<DataTrigger Binding="{Binding ElementName=flowTreeView, Path=SelectedItem.hasInput}" Value="0" >
<Setter Property="Visibility" Value="Hidden"/>
</DataTrigger>
</Style.Triggers>
</Style>
</DockPanel.Style>
Before my question, this app has a TreeView with some nodes. When i select a node that requires user input, it shows the previous DockPanel. The DockPanel also contains a StackPanel below the DockPanel.Style.
As you can see, this DockPanel starts with Visibility=Hidden. Then, when the trigger fires where SelectedItem.hasInput has the value=1, it sets the Visibility of the DockPanel to Visible and it's supposed to focus my TextBox txtBoxPopUp. The problem is when i click the node, nothing happens(does not show the DockPanel). But if i remove the second Setter(which give focus to TextBox), the DockPanel appears normally. Other strange behavior, with the 2 Setters, if i click several times the Node that requires user input it brings the DockPanel with the TextBox focused, but is happens only sometimes.
Conclusion, i want to focus the TextBox when the DockPanel it's visible, but i am not able to do that.

<Style TargetType="DockPanel">
<Setter Property="Visibility" Value="Hidden"/>
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=flowTreeView, Path=SelectedItem.hasInput}" Value="1" >
<Setter Property="Visibility" Value="Visible"/>
<Setter Property="FocusManager.FocusedElement" Value="{Binding ElementName=txtBoxPopUp}"/>
</Style.Triggers>
</Style>
You do not need to have the second data-trigger (setting to Hidden). Since this is already the default value, there's no need to have it.

Related

Wpf mahapps collapse datagrid row by condition not working

I need to hide rows under a certain condition, I do this through a style trigger. But for some reason it doesn't work if you use Map apps styles. If I delete styles from the dictionary, everything works. What i need to do to make it work with Mah app styles as well?
<DataGrid.ItemContainerStyle>
<Style TargetType="DataGridRow">
<Style.Triggers>
<DataTrigger Binding="{Binding Path=IsArchive}" Value="True">
<Setter Property="Visibility" Value="Collapsed" />
</DataTrigger>
</Style.Triggers>
</Style>
</DataGrid.ItemContainerStyle>
I also tried using baseOn but it still doesn't work
Set the RowStyle instead of ItemContainerStyle:
<DataGrid.RowStyle>
<Style TargetType="DataGridRow" BasedOn="{StaticResource MahApps.Styles.DataGridRow}">
<Style.Triggers>
<DataTrigger Binding="{Binding Path=IsArchive}" Value="True">
<Setter Property="Visibility" Value="Collapsed" />
</DataTrigger>
</Style.Triggers>
</Style>
</DataGrid.RowStyle>

Window.Visibility won't update through trigger

I'm trying to set a trigger to hide my window whenever a property in my ViewModel changes. I tried using the same trigger on a different element and that worked exactly as expected, so it appears that I cannot change the visibility property of a window using a trigger. Are there any workarounds I can use to hide my window?
<Window.Style>
<Style TargetType="Window" BasedOn="{StaticResource Shell}">
<Setter Property="Visibility" Value="Hidden"/>
<Setter Property="Left" Value="{Binding SecondDisplayLeftSide}"/>
<Style.Triggers>
<DataTrigger Binding="{Binding ShellType}" Value="InstructorMultiDisplay">
<Setter Property="Visibility" Value="Visible"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Window.Style>

How to stop DataGrid row color from changing?

I've implemented code to get around the double click issue when selecting a row in a WPF DataGrid. I'm using the following code from here: https://stackoverflow.com/a/5857908/40106.
<Style TargetType="DataGridCell">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="IsEditing" Value="True" />
</Trigger>
</Style.Triggers>
</Style>
Rows have alternating colors. The problem is when I mouse over a row, in one column, the light blue color is replaced by white.
The above code works great except for this one issue. How do I stop the color from changing when mousing over a row?
I have tried the following but it doesn't have any effect:
<Style TargetType="DataGridCell">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="IsEditing" Value="True" />
<Setter Property="Background" Value"AliceBlue" />
</Trigger>
</Style.Triggers>
</Style>
The problem is, that the cell will display it's edit style when you hover the mouse above the cell.
For a DataGridTextColumn this means, that a TextBox with a white background is displayed.
You can set a Style to <DataGridTextColumn.EditingElementStyle> and set the Background to transparent.
<DataGridTextColumn Header="Name" Binding="{Binding Name}" >
<DataGridTextColumn.EditingElementStyle>
<Style TargetType="TextBox">
<Setter Property="Background" Value="Transparent"></Setter>
<Setter Property="BorderThickness" Value="0"></Setter>
</Style>
</DataGridTextColumn.EditingElementStyle>
</DataGridTextColumn>
To get the white Background, when actually editing the cell you could add another trigger to the IsSelected event:
<Style TargetType="DataGridCell">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="IsEditing" Value="True" />
</Trigger>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Background" Value="White"/>
</Trigger>
</Style.Triggers>
</Style>
Another option would be to apply the DataGridCell Style to CheckBoxColumns only. For other Column types it wouldn't make a difference anyway.

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

Using Bindings to trigger a style change

Hopefully someone can help here.
I have a ListView that is populated by a List Property in my ViewModel.
I have another List Property in my ViewModel that contains the Rows in the UI I need highlighting.
<ListView.Resources>
<Style TargetType="ListViewItem">
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Foreground" Value="Red"/>
</Trigger>
</Style.Triggers>
</Style>
</ListView.Resources>
This does exactly what is looks like, any item I select in the ListView highlights in Red.
I want to be able to Bind this style trigger to the List property in my ViewModel.
Anybody know how this can be achieved?
Create a property called IsSelected on your item and bind it to your ListViewItem.IsSelected
<Style TargetType="ListViewItem">
<Setter Property="IsSelected" Value="{Binding IsSelected}" />
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Foreground" Value="Red"/>
</Trigger>
</Style.Triggers>
</Style>
Edit
If you want to apply other style setters based on a property in your DataItem, use a DataTrigger instead of a regular Trigger. Regular Triggers are only meant to be used on UI Element properties, not bindings.
<Style TargetType="ListViewItem">
<Style.Triggers>
<DataTrigger Binding="{Binding IsHighlighted}" Value="True">
<Setter Property="Foreground" Value="Red" />
</DataTrigger>
</Style.Triggers>
</Style>

Categories