WPF toggle button how to switch between 2 customized brushes - wpf

Hi I'm new to the WPF world.
I am working with a Toggle button and not sure how I can switch between 2 brushes.
Basically I have 2 brushes that each defines a XAML image, both of them are stored in a ResourceDictionary. One brush should by default shown and the other one should be shown when IsChecked property is true.
I kind know that I need to wrap them into styles and should use a trigger to toggle them but I am not familiar with the syntax how to do this.
What's the generic way to do this?
Any suggestion is appreciated.

Generically:
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=Name, Path=IsChecked}" Value="true">
<DataTrigger.EnterActions>
<!-Set The Brush That You Want To Use-->
</DataTrigger.EnterActions>
</DataTrigger>
</Style.Triggers>

Related

Datagrid styling row colors for changed values

I'm looking for a way to change the Color of a complete row in a WPF DataGrid.
My implementation requires configuration information and I want to make it obvious to the user that a value has changed. I'm wanting the default Color to be black, but to display red when a value has changed.
I have a property, IsChanged, which reflects the status of the item which I wish to use to Style the Row.
Is there a way of achieving this?
I'd suggest you use a DataTrigger to set the background when IsChanged is true.
Something like:
<Style>
<Style.Triggers>
<DataTrigger Binding="{Binding IsChanged}" Value="true">
<Setter Property="Background" Value="#FFFF0000" />
</DataTrigger>
</Style.Triggers>
</Style>
You will also need to make the IsChanged property a Dependency Property to allow binding to it.

How to change the control template effectively in WPF?

The subject is that I've defined a customized control bound to a DataContext. And I wished to change the control template dynamically according to the DataContext's specific property values.
There're 2 ways I've thought of,but I have no idea about which way is better.
1.Do not use the control template in a ResourceDictionary and all details of the control are defined in C# code.Use the DependencyProperty CallBack method to render the control when DataContext's property values change.
2.Define control template in the ResourceDictionary and use DataTrigger to change the 'Control.Template' property.
In my application,thousands of instances in this type would be created,so it's really unacceptable if the ControlTemplate changging is not effective.
Could you please give me some advices or better solutions?
Using any standard WPF technique might not be effective if it would involve a thousands of instances of complex controls. See http://msdn.microsoft.com/en-us/magazine/dd483292.aspx.
I would go with MultiBinding + IMultiValueConverter to Control.Template dependency property, since Template would depend on multiple DataContext properties and would, perhaps, involve complex logic.
Perhaps you could used a ContentPresenter in your ControlTemplate to customize parts of your control. You could provide DataTemplates for those customizable parts which are automatically applied.
I would use a style with the data triggers to control which template is displayed. Like this example:
<Style x:Key="Die1Face" TargetType="{x:Type Button}">
<Setter Property="Template" Value="{StaticResource dieNone}" />
<Style.Triggers>
<DataTrigger Binding="{Binding Path=ThrowDie1[0]}" Value="1" >
<Setter Property="Template" Value="{StaticResource dieOneA}" />
</DataTrigger>
<DataTrigger Binding="{Binding Path=ThrowDie1[0]}" Value="2" >
<Setter Property="Template" Value="{StaticResource dieTwoA}" />
</DataTrigger>
</Style.Triggers>
</Style>
This would give the flexibility you need.

Popup vs. Visibility toggle

I have a couple of views that I display as overlays on the main window by binding the visibility to a boolean property in my ViewModel.
The main window looks something like this:
<Grid>
<vw:MainContentView/>
<!-- Overlays (normally invisible) -->
<vw:NotificationsView/>
</Grid>
The 'NotificationsView' has a style that looks like this:
<Style x:Key="NotificationsView" TargetType="UserControl">
<!-- snipped -->
<Style.Triggers>
<DataTrigger Binding="{Binding IsNotificationsViewVisible}" Value="True">
<Setter Property="Visibility" Value="Visible"/>
</DataTrigger>
<DataTrigger Binding="{Binding IsNotificationsViewVisible}" Value="False">
<Setter Property="Visibility" Value="Collapsed"/>
</DataTrigger>
</Style.Triggers>
</Style>
I am wondering whether it might be preferable to use a Popup with the 'IsOpen' property bound to the 'IsNotificationViewVisible' property in the ViewModel, rather than toggling the visibility of the view directly:
<Grid>
<vw:MainContentView />
<!-- Popups (normally invisible) -->
<Popup IsOpen="{Binding IsNotificationsViewVisible}">
<vw:NotificationItemsView/>
</Popup>
</Grid>
Are there any reasons I'd want to use one approach over the other (memory usage or otherwise)? Both approaches seem to work just fine - the Popup comes with a couple of free animations but otherwise looks the same.
If you're displaying content on an already existing window, you should probably use the Visibility approach. The Popup acts as a mini-window that can initially position itself based on the location of elements in the main window. That means that it can go outside the bounds of the main window and won't move around when you move the main window. It also doesn't effect the layout of other elements in the window. I imagine it also has some overhead associated with this, but I have not run any exact numbers.
As a bonus, I'll throw in a suggestion: you could use a converter to make Visibility binding easier.

WPF databind Image.Source in MVVM

I'm using MVVM and am trying to databind the Source property of Image to my ViewModel in such a way that I can change the icon on the fly. What is the best pattern to follow for this? I still have the flexibility to change my ViewModel to suit, but I don't know where to start in either the xaml or ViewModel.
To be clear, I don't want my ViewModel to know about the specific images (that's for the View to know), just the state that triggers different images. For now I have just two states, lets say Red and Green. Should I create an Enum property or a bool? And then how do I databind to switch the image source?
You can use a DataTrigger, and change the image (entirely in XAML) based on the value of a property in your ViewModel. I, personally, would use an enum, since you may want multiple states.
VisualStateManager will work for this as well, but will require WPF Futures or .NET 4.
In order to use a DataTrigger, you can do something like:
<Image>
<Image.Style>
<Style TargetType="Image">
<Setter Property="Source" Value="1.png" />
<Style.Triggers>
<DataTrigger Binding="{Binding ViewModelEnumProperty}" Value="Image2">
<Setter Property="Source" Value="2.png" />
</DataTrigger>
</Style.Triggers>
</Style>
</Image.Style>
</Image>
This will use "1.png", but when your enum is set to "Image2" in the VM, it'd switch to 2.png. More DataTriggers can be added as needed.

WPF Trigger for IsSelected in a DataTemplate for ListBox items with Blend

I wanted to change the Foreground color when I selected a listboxItem and I did it using this bit of code:
<DataTrigger Binding="{Binding
RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type ListBoxItem}},Path=IsSelected}" Value="True">
<Setter TargetName="descriptionTB" Property="Foreground" Value="#000"/>
</DataTrigger>
You can find the answer here.
But if I want a designer to do this in Blend, how would he do it without drilling into xaml?
Thank you
Artur,
The Triggers designer in Expression Blend only allows adding and modifying EventTriggers and Property triggers. I haven't found a way to add DataTriggers with Blend. I'm also not sure how to set RelativeSource Binding using Blend either. I've always handed code the XAML for test and use Blend for everything else.
Maybe I'm misunderstanding the question but can't you just create a style resource for descriptionTB and let the designer only deal with that style definition and not the binding?
<DataTrigger Binding="..">
<Setter TargetName="descriptionTB" Property="Style" Value="{StaticResource DescriptionTextBoxStyle}" />
</DataTrigger>
In the resources section of your control or window you add the style definition:
<Style TargetType="{x:Type TextBox}" x:Key="DescriptionTextBoxStyle">
<Setter Property="Foreground" Value="#000" />
</Style>
If you want to further isolate the designer from the mechanics of the UI you can create a resource dictionary in a separate xaml file in which you can collect all styles meant for the designer. Then you can merge that resource dictionary with your control's or application's main resources.

Resources