Automatically refresh ListView from a checkbox - c#

I have a ListView that's bound to a simple array of objects (mainly getters / setters). It shows after the main code has run as a simple report. Initially the dialog just shows the items that changes. I have "Show All Details" checkbox that the user can check to see all items. I have a MultiTriggger setup on the checkbox and the "ZeroChanged" property. The issue seems to be that the ListView needs to be told to refresh when the checkbox changes state so that the MultiTrigger will then adjust the Visibility Value = "Collapsed" action. I'm starting to think that I'll need some supporting C# code to process the checkbox and then refresh the ListView. The array of objects doesn't change, it's fixed output from the main program. The check box defaults to false Is this possible with just XAML?
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Style.Triggers>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding ElementName=_showAllDetailsChkBox}" Value="False" />
<Condition Binding="{Binding ZeroChanged}" Value="True" />
</MultiDataTrigger.Conditions>
<Setter Property="Visibility" Value="Collapsed" />
</MultiDataTrigger>
</Style.Triggers>
</Style>
</ListView.ItemContainerStyle>

If you bind to the IsChecked property of the CheckBox, the Visibility property of the ListView should get set as soon as you check or uncheck the CheckBox. You are missing a binding path:
<Condition Binding="{Binding Path=IsChecked, ElementName=_showAllDetailsChkBox}" Value="False" />
<Condition Binding="{Binding ZeroChanged}" Value="True" />

Related

WPF: Conditionally put focus on checkbox and button

I want to set focus on conditionally in a WPFform. Here I have two types of control. One is 'checkbox' and other one is button. The checkboxes are getting enabled on some condition, however the button control(s) are visible by default. I am able to put focus on button(s) whether checkboxes are getting enabled or not. Though checkboxes should get focus over button when checkboxes are getting enabled. Kindly, suggest an approach to achieve this please. I have used following code to achieve focus on button(s)
<Style x:Key="FocusElement" TargetType="Grid">
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=chkCA, Path=IsVisible}" Value="True">
<Setter Property="FocusManager.FocusedElement" Value="{Binding ElementName=chkCA}"/>
</DataTrigger>
<DataTrigger Binding="{Binding ElementName=btnSaveAll, Path=IsVisible}" Value="True">
<Setter Property="FocusManager.FocusedElement" Value="{Binding ElementName=btnSaveAll}"/>
</DataTrigger>
</Style.Triggers>
</Style>
Thanks!

Control a button's enabled state using 3 multi data triggers

I want to control a buttons IsEnabled state based on the following conditions. The button should be active only when :
Checkbox 1 or Checkbox 2 is checked.
Listbox contains atleast 1 list item.
My issue is : I have to use separate MultiDataTrigger for achieving this behavior. When I add the code to the first multidata trigger, it doesn't work. ie even if list box doesn't have any items, the button is getting enabled.
So I need a solution for this. is there any possible way to include the 3rd multi data trigger condition along with the 2 conditions, so that few lines of code can be saved?
Thanks in advance. Please check my code below.
<Button.Style>
<Style TargetType="Button">
<Style.Triggers>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding ElementName=Checkbox1, Path=IsChecked}" Value="False" />
<Condition Binding="{Binding ElementName=Checkbox2, Path=IsChecked}" Value="False" />
</MultiDataTrigger.Conditions>
<Setter Property="IsEnabled" Value="False" />
</MultiDataTrigger>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding ElementName=ListBox, Path=Items.Count}" Value="0" />
</MultiDataTrigger.Conditions>
<Setter Property="IsEnabled" Value="False" />
</MultiDataTrigger>
</Style.Triggers>
</Style>
</Button.Style>
The MultiTrigger applies the associated setters or actions when all of the conditions are true (binary AND operation).
As mentioned, the trigger will fire on all the conditions being AND'd, which was why it didn't work when you put all the conditions together. The easiest way to produce an OR (without implementing a IMultiValueConverter), is to have multiple datatriggers (which imply a binary OR operation).
If you are intent on saving lines of code, you can use a DataTrigger instead of the MultiDataTrigger.
<DataTrigger Binding="{Binding ElementName=listView, Path=Items.Count }" Value="0">
<Setter Property="IsEnabled" Value="False" />
</DataTrigger>

Set Background of button based on Content or CustomDP value

I have a button whose Content property keeps changing based on certain conditions which are set from the ViewModel. Essentially it gets set a value from 0 to 1000.
I also have another custom DP property on the same button whose value can be set to a certain enum.
What I am trying to solve is as follows (and unfortunately have no idea how I should go about it):
If my button content value is 0 - background of the button should be Gray.
If my button content value is 1 - background of the button should be Yellow.
If my button content value is 1 & the Custom DP has a value set (not the default value) - background should change to Red.
If my problem statement was just dealing with setting a background based on the integer set on the content - I could easily use Converters (String to Brush) and set my background. But the last condition which is now setting my background based on custom DP value coming in - have no idea how to solve...
Can somebody please suggest me an approach - sample code to solve such a problem.
<Button Content="0">
<Button.Style>
<Style TargetType="Button">
<Style.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Self},Path=Content}" Value="0">
<Setter Property="Background" Value="Gray"/>
</DataTrigger>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Self},Path=Content}" Value="1">
<Setter Property="Background" Value="Yellow"/>
</DataTrigger>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding RelativeSource={RelativeSource Self}, Path=Content}" Value="1"/>
<Condition Binding="{Binding RelativeSource={RelativeSource Self}, Path=YourDP}" Value="YourValue"/>
</MultiDataTrigger.Conditions>
<MultiDataTrigger.Setters>
<Setter Property="Background" Value="Red"/>
</MultiDataTrigger.Setters>
</MultiDataTrigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
You can use multi-conditions triggers or multi data triggers. See this link and this link.

MultiDataTrigger not working with binding path condition

I have implemented a WPF user control and what i want to achieve here is on mouseover on Main Grid some stack panels should hide. And i need to have multiple triggers conditions. Despite looking everywhere i am unable to find what am i doing wrong. UserControl Resources are as follow
<UserControl.Resources>
<Style x:Key="StackViewStyle" TargetType="{x:Type StackPanel}">
<Style.Triggers>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding RelativeSource={RelativeSource AncestorType=Grid},Path=IsMouseOver}" Value="True" />
<Condition Binding="{Binding Path=FileState, RelativeSource={RelativeSource Self}}" Value="Uploading" />
</MultiDataTrigger.Conditions>
<Setter Property="Visibility" Value="Collapsed"/>
</MultiDataTrigger>
</Style.Triggers>
</Style>
</UserControl.Resources>
Data binding is working fine, because when i put in a test label to check its value it was "uploading". If i remove FileState Condition it starts working. I am using it as
<StackPanel Name="StackViewCount" Style="{StaticResource StackViewStyle}">
...
</StackPanel>
While looking output window i found this error
BindingExpression path error: 'FileState' property not found on 'object' ''StackPanel' (Name='StackViewCount')'. BindingExpression:Path=FileState; DataItem='StackPanel' (Name='StackViewCount'); target element is 'StackPanel' (Name='StackViewCount'); target property is 'NoTarget' (type 'Object')
So how can i tell the binding to look for FileState in UserControl not stackpanel
Now when i changed condition to
<Condition Binding="{Binding Path=FileState}" Value="Uploading" />
I dont see any errors but still it does not work.
Since FileState is property of your UserControl and it is ancestor of StackPanel you have to bind to ancestor like:
<Condition Binding="{Binding Path=FileState, RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}" Value="Uploading" />

Datagrid multitrigger referencing values from code-behind

I'm still bloody green in WPF and have not yet fully grasped the concept behind it. I've got the following problem:
I want to set triggers in a datagrid depending on a precondition.
Example:
In my code-behind, I have a string variable, let's call it variableString. Now depending on the the value of variableString, I want to enable/disable the triggers inside a datagrid, that I have defined in XAML like:
if(variableString == "a")
then
XAML
<DataGrid AutoGenerateColumns="False" Margin="5,5,0,75" Name="dataGrid1" ItemsSource="Binding}">
<DataGrid.ItemContainerStyle>
<Style TargetType="DataGridRow">
<Style.Triggers>
<DataTrigger Binding="{Binding Path=SomeColumnName}" Value="someValue">
<Setter Property="Background" Value="White"/>
<DataTrigger Binding="{Binding Path=SomeColumName}" Value="someOtherValue">
<Setter Property="Background" Value="Red"/>
</Style.Triggers>
</Style>
</DataGrid.ItemContainerStyle>
Otherwise, if
if(variableString == "b")
then
Do Nothing`
I've already tried binding the string to the datacontext of the datagrid, but that was rather contra-productive, as it removes my binding to the database.
Can anyone help me here. An example, a push in the right direction etc...
I really like the options that WPF gives you, however it's that fundamental things, that were so easy to handle in WinForms, that drive me mad in WPF.
Thanks
I think you want a MultiDataTrigger, which allows you to base your trigger off of multiple values
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding Path=SomeColumnName}" Value="someValue" />
<Condition Binding="{Binding RelativeSource={RelativeSource AncestorType={x:Type Window}}, Path=variableString}" Value="A" />
</MultiDataTrigger.Conditions>
<Setter Property="Background" Value="White" />
</MultiDataTrigger>
To find your string in the code behind, you'll probably have to use some kind of RelativeSource binding to find the class containing that property. My example assumes there is a public property called variableString on the Window class

Categories