I want to make my gridsplitters in a custom user control have visibility collapsed
based on when the parent control has loaded some data using a load button? I thought that the way to do this would be to create a property dataloaded on the parent control and then set a trigger in the triggers of the usercontrol like below:
but I can't seem to get it to reference the property of the usercontrol (graphviewer).
Also, can property triggers reference other controls within the control like I did below? I am assuming either my syntax is wrong or what I am trying to do is not possible. So Far I have only messed with a few basic properties within trigger templates when making modifications to control templates, so I don't really know whether what I am trying to do is possible.
<UserControl.Triggers>
<Trigger Property="GraphViewer.DataLoaded" Value="true">
<Setter Property="SignalNameGridSplitter.Visibility" Value="Visible" />
</Trigger>
</UserControl.Triggers>
Try this... first add the XML Namespace of your GraphViewer control - something like this:
xmlns:YourXmlNamespace="clr-namespace:YourApplicationName.FolderNameIfApplicable"
Then add this into a Style... it has to be in a Style.Triggers collection because you can't use a DataTrigger in a UserControl.Triggers collection:
<UserControl.Style>
<Style>
<Style.Triggers>
<DataTrigger Binding="{Binding DataLoaded, RelativeSource={RelativeSource
FindAncestor, AncestorType={x:Type YourXmlNamespace:GraphViewer}}}" Value="True">
<Setter Property="SignalNameGridSplitter.Visibility" Value="Visible" />
</DataTrigger>
</Style.Triggers>
</Style>
</UserControl.Style>
Related
XAML
<utility:InvalidNotification x:Name="InvalidNotificationControl"/>
<Button Content="Clean AppV Cache" Click="Button_Click">
<Button.Style>
<Style TargetType="Button">
<Setter Property="IsEnabled" Value="True"/>
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=InvalidNotificationControl, Path=Visibility}" Value="Visible">
<Setter Property="IsEnabled" Value="False"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
NOTE
InvalidNotification is a custom UserControl
Now, the DataTrigger works fine initially and disable the button since the Usercontrol is visible.
The problem is when I collapse the Usercontrol based on another condition the button stays disable. I found this related answer which states that The properties changed by triggers are automatically reset to their previous value when the triggered condition is no longer satisfied. which is not my case. Why is that ?
EDIT
Thanks to #mm8 which led me to the solution. So if ever you're trying to bind a control on a UserControl's content (inner TextBlock in my case), just add a second trigger at the bottom of your Usercontrol like so,
<UserControl.Style>
<Style TargetType="UserControl">
<Setter Property="Visibility" Value="Collapsed"/>
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=Notification, Path=Visibility}" Value="Visible">
<Setter Property="Visibility" Value="Visible"/>
</DataTrigger>
</Style.Triggers>
</Style>
</UserControl.Style>
where notification would be the name of my TextBlock
Your example works provided that you toggle/set the Visibility property of the InvalidNotification control itself, since it is this property that you bind to.
If you set the Visibility property of some element within the InvalidNotification control, you need to bind to this specific element.
You can't do this using an ElementName binding though because the Button and any element defined in the InvalidNotification control don't belong to the same namescope.
I've created a ResourceDictionary that defines a bunch of System.Windows.Shapes.Path that are used in the ContentPresenter of a Button ControlTemplate.
I'd like to change one of the Paths out based on a ViewModel property. If true the button uses one path from the ResourceDictionary, if false a different one.
Currently I just reference a StaticResource in the xaml to point directly to the path I want displayed.
What's the best way to do this?
You would have to modify the content template of the button in style by referring to the elements from you resource dictionary.
Something like this:
<Button.Style>
<Style TargetType="Button">
<Setter Property="ContentTemplate" Value="{StaticResource cp2}"></Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="ContentTemplate" Value="{StaticResource cp1}"></Setter>
</Trigger>
</Style.Triggers>
</Style>
</Button.Style>
I have used mouse over property as my trigger to change the content template.
You can use DataTrigger instead of Trigger
I wonder what the best design is to show different content dynamically in a list view.
What I want is (e.g.) depending on a radio button, a list view be filled with items (setting ItemsSource, changing column width, names and the row information itself).
What I'm currently doing is dynamically changing all the list view properties.
I wonder if it would be better to use multiple list views (maybe even as user controls), all on the same window position and hide all non-used.
Also, since I'm using MVVM Light/WPF I want to easily connect it to the XAML code if possible.
If changes in ItemsSource occur in time (or you want change it depending on some conditions like RadioButton's IsChecked property) you need to reflect on change your DataTemplate. The way out is to create DataTrigger which will swap your DataTemplates based on some criteria.
<ListView>
<ListView.Style>
<Style TargetType="ListView">
<Setter Property="ItemsSource" Value="{Binding InitalSource}"/>
<Setter Property="ItemTemplate" Value="{StaticResource InitialDataTemplate}"/>
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=RadioButton, Path=IsChecked}" Value="True">
<Setter Property="ItemsSource" Value="{Binding AnotherSource}"/>
<Setter Property="ItemTemplate" Value="{StaticResource AnotherDataTemplate}"/>
</DataTrigger>
</Style.Triggers>
</Style>
</ListView.Style>
</ListView>
Whenever condition of DataTrigger stops being true all changes made by Setters vanish, by default, therefore you do not need to add another DataTrigger in case of False value for RadioButton's IsChecked.
Is there a way to do this, or do I have to create an IsSelectedProperty on the ViewModel and Bind to that instead?
I would like to be able to do something like Source={Binding RelativeAncestor ListViewItem}
but instead there is only this property sourcename which I can use to set triggers based off of the items in the datatemplate if I name them using x:Name
<HierarchicalDataTemplate.Triggers>
<Trigger SourceName="" Property="IsSelected" Value="True">
<Setter TargetName="bdr" Property="Foreground" Value="White"/>
<Setter TargetName="bdr" Property="Foreground" Value="Red"/>
</Trigger>
</HierarchicalDataTemplate.Triggers>
Looking back, I realized that yesterday I made a very confusing post. Also, considering how hard I find it to even interpret people's comments to my questions, I should probably give more detail.
I know that in wpf you can set triggers based on the control by setting a style for the target control type.
In addition you also have data triggers that can trigger off of properties in the datacontext. What I was hoping was that there was a way to use triggers, or datatriggers to set a property when the datacontext is an object of a specific type.
is this possible? If not, I will just accept the provided answer as applicable in my situation, but since this will require me to add a property to my viewmodel, it seemed reasonable to check if there was a way to just check item type rather than having to check the actual property.
I would suggest that you bind the IsSelected property in your view model, but that's just me.
I'm not sure how complex your HierarchicalDataTemplate is, or if some items need to have their Foreground changed, and some don't; but I'm going to assume you want to update the item that is selected throughout the entire TreeView (if that's what this is for).
If that is the case, just add DataTriggers to the Style of the TreeViewItem:
<Style TargetType="TreeViewItem">
<Setter Property="IsSelected"
Value="{Binding IsSelected, Mode=TwoWay}" />
<Style.Triggers>
<DataTrigger Binding="{Binding IsSelected}" Value="True">
<Setter Property="Foreground"
Value="Red" />
</DataTrigger>
<DataTrigger Binding="{Binding IsSelected}"
Value="False">
<Setter Property="Foreground"
Value="Black" />
</DataTrigger>
</Style.Triggers>
</Style>
Note that you don't need to bind the IsSelected parameter if you don't want to, its just there because it's in my code.
Im trying to make an event trigger using a button to tell the ListView each time to resize it columns automatically.
ive used different methods but non of them worked, the event is in this code defined inside the ListView and im trying through DataBinding to take the action (IsPressed) from the Button trigger the ListView.
when i try to execute the code i get the following error
The tag 'Binding' does not exist in XML namespace 'http://schemas.microsoft.com/winfx/2006/xaml/presentation'.
im doing the DataBinding in a wrong way? will this code in this way work at all?
thanks in advance!
<ListView.Style>
<Style>
<Style.Triggers>
<Trigger Binding = "{Binding ElementName=Button1,Path=IsPressed}" Value="True">
<Setter Property="GridViewColumn.Width" Value="Auto"/>
</Trigger>
</Style.Triggers>
</Style>
</ListView.Style>
To bind a Trigger to a property outside the element scope use DataTrigger
Example:
<DataTrigger Binding="{Binding ElementName=Button1, Path=IsPressed}" Value="True">
<Setter Property="GridViewColumn.Width" Value="Auto"/>
</DataTrigger>
A regular trigger(Property Trigger) only responds to dependency properties, which you are trying as of now:
<Style.Triggers>
<Trigger .....
Use DataTrigger, it can be bound to another control
<Style.Triggers>
<DataTrigger Binding="{Binding