WPF - using IsInitialized as Property Trigger fails - wpf

The object is an ListBoxItem, although I tried with a Panel as well.
I get this error message: Property can not be null on Trigger., within an InvalidOperationException.
Here's the trigger:
<Trigger Property="IsInitialized" Value="true">
<Setter TargetName="MyPanel" Property="Background" Value="AliceBlue">
</Setter>
</Trigger>
Note: I can't use Loaded, because I don't want it to fire whenever the control is rendered. Just at initializiation.
This property exists... why doesn't it work?

This is because the IsInitialized property is not a Dependency Property. Triggers can only be used with dependency properties.
But the question is why would you need such a trigger? Because the same effect can be achieved just by specifying the Background property directly on MyPanel or in the style of `ListBoxItem'.

Related

Set property after command

I have a StatusBar below the screen in SL4 (using PRISM), just a very simple Telerik RadDockPanel.
I also have a menu (Telerik RibbonView with RadRibbonGroup and RadRibbonToggleButton). When the toggle button is pressed, I want to set the text to 'ON' and 'OFF', and I want to hide the status bar, but... only in XAML (not using code behind).
I believe this is a common SL/WPF coding practice... but how ?
Have to use EventTrigger (check example bellow on page by link that I provided) and ObjectAnimationUsingKeyFrames to change properties that aren't animated (Text, Visibility so on).
Check good example in other answer on so.
You can specify a DataTrigger in your window like this -
<StatusBar.Style>
<Style>
<Style.Triggers>
<DataTrigger
Binding="{Binding ElementName=MyRadRibbonToggleButton, Path=IsChecked}"
Value="True">
<Setter Property="Grid.Visibility" Value="Collapsed" />
</DataTrigger>
</Style.Triggers>
</Style>
</StatusBar.Style>
In case you can't use ElementName binding then you can use a property in your ViewModel(corresponding to RadRibbonToggleButton state). Similar Trigger can be created for a TextBlock/Label to show On/Off text.
This is how I implement this kind of functionality in WPF/MVVM applications;
You may have to apply some hack to make this work with telerik controls.

Let one control be enabled/disabled based on another control

I have two DataGrid's that I want do have enabled/disabled based on whether precisely 1 element is selected in another DataGrid. What is the simplest way to accomplish this dependency control in WPF?
You could use a trigger:
<DataGrid.Style>
<Style TargetType="DataGrid">
<Setter Property="IsEnabled" Value="False"/>
<Style.Triggers>
<DataTrigger Binding="{Binding SelectedItems.Count,
ElementName=datagrid1}"
Value="1">
<Setter Property="IsEnabled" Value="True"/>
</DataTrigger>
</Style.Triggers>
</Style>
</DataGrid.Style>
You could:
Create an IValueConverter, perhaps it is called NotEqualToOneBooleanConverter
Bind IsEnabled from one DataGrid to the SelectedItems.Count on the other
Set the Converter on this Binding to be the NotEqualToOneBooleanConverter
This approach is nice since once your converter is created, it can be applied throughout your XAML and to any type and any property (not just DataGrid or SelectedItems.Count). To make it even more flexible, you could have a more generic version of this converter that could compare any two values specified directly from XAML (one from the Binding and one specified as property on the Converter).
The downside to this approach - it's XAML only, and difficult to test especially if what you are trying to achieve is a business requirement and not just a graphical effect.
Hope this helps!
This is my quick hack:
tablesControl.SelectionChanged += (sender, sce) =>
{
var c = tablesControl.SelectedItems.Count;
var orderingPossible = c == 1;
itemsControl.IsEnabled = orderingPossible;
};
In the first Grid have an event or Command that is fired when you click on that cell, in this event you need to have some bool property you can set to false, then bind the Enabled property to this bool. If you are using MVVM this will be very easy, have a look at this to see how - http://www.youtube.com/watch?v=tKfpvs7ZIyo

WPF button styling depending on active view

I'm using Caliburn Micro to develop a simple MVVM WPF application.
My ShellView has a single ContentControl and three buttons each which bind to a public method in my ShellViewModel, lets say ActivateView1, ActivateView2 and ActivateView3.
My ShellViewModel inherits from Conductor and each Activate method calls ActivateItem(new View1ViewModel()), etc.
So far so good. When I click a button, a new view gets activated in the ContentControl. The problem is that I need each button to change style when its "associated view" is active and I have really no idea how to achieve this functionality. Do you have any suggestions?
I'm fairly new to Caliburn Micro and WPF-styling so any help will be much appreciated.
I am not very sure about this but still I can think of something like this,
you can create a style and add the style to your button. something like this
<Style x:Key="ButtonStyle1" TargetType="{x:Type Button}">
<Style.Triggers>
<Trigger Property="IsPressed" Value="True">
<Setter Property="Fill" TargetName="yourButtonName" Value="Black"/>
<Setter Property="Margin" TargetName="yourButtonName" Value="5,0,5,0"/>
</Trigger>
</Style.Triggers>
</Style>
and you can add this style to your button.
I can think of two possible options you could use:
You could bind your buttons style properties to properties on you ShellViewModel. In those properties you can determine the style to return based on the shells Active view i.e.
return ActiveItem == button1ViewModel ?
(Style) App.Current.Resources["Button1ActiveStyleKey"] :
(Style) App.Current.Resources["Button1InactiveStyleKey"];
this would mean your ViewModel would be aware of Styles which you may not want. If that is the case option two would be to write a Caliburn.Micro IResult which changes the style of the button and return 3 of those (one for each button) from a Coroutine that is invoked via the button click i.e.
public IEnumerable<IResult> ButtonOneClicked()
{
yield return new ChangeButtonStyle("Button1Name", "Button1ActiveStyleKey");
yield return new ChangeButtonStyle("Button2Name", "Button2InactiveStyleKey");
yield return new ChangeButtonStyle("Button3Name", "Button3InactiveStyleKey");
}
The implementation of the ChangeButtonStyle IResult would search the view (provided via the ActionExecutionContext parameter to IResult.Execute) for a control with the name provided to the 1st parameter of ChangeButtonStyle ctor, and then set the style property of that control using the resource key provided as the 2nd paramter to the ChangeButtonStyle ctor.
You can use
<Trigger Property ="IsPressed" Value ="True">
I think it does the trick...

WPF/MVVM: Disable a Button's state when the ViewModel behind the UserControl is not yet Initialized?

I have a DocumentListView.Xaml with a ListBox and 3 Buttons.
Behind that UserControl sits a DocumentListViewModel with 3 Buttons and their Command Property bound to 3 RelayCommands.
I have 3 Controller like AdministrationController, BillingController, ReportController.
Every Controller has ObservableCollections like Customer 1 : N Order 1: N Document same for the other Controller.
In one Controller I have a special binding situation. When my DocumentListViewModel is not initialized by its parent ViewModel like OrderViewModel (because no orders are loaded/exist) then my UserControl has 3 buttons which are ENABLED. Ok the user can press the 3 buttons and nothing happens but still its very confusing and above all the consistency in my user interface is gone.
How can I set the Command of a Button as default to "Disabled" ?
Setting the Buttons IsEnabled property to false does not help because the button will stay forever in the disabled state. No CanExecute TRUE will set it to IsEnabled = true.
AND I do not want to introduce another property IsButtonEnabled... that stupid because then I have both worlds winforms and wpf behind my buttons logic... ICommand should be enough.
Or you can use a Style for the button to disable:
<Style TargetType="{x:Type Button}" x:Key="DisablerButton">
<Style.Triggers>
<Trigger Property="Command" Value="{x:Null}">
<Setter Property="IsEnabled" Value="False" />
</Trigger>
</Style.Triggers>
</Style>
This is an interesting situation. Honestly I've never run into the case where the UI was loaded and interactive but the ViewModel was not yet bound.
However, ignoring that for a moment, you could potentially use a FallbackValue on your binding to bind to a globally available NullCommand or something that always returns false for its CanExecute method.
<Button Command="{Binding SaveCommand, FallbackValue={StaticResource NullCommand}}" />

WPF Data Triggers Set Object properties based on events

With DataTriggers in WPF its possible to set properties on controls based on the the object you have bound. For example you could set the Background of a TextBlock based on a IsAlive property on your object.
<DataTrigger Binding="{Binding Path=IsAlive}" Value="true">
<Setter Property="Background" Value="Yellow"/>
</DataTrigger>
I want to know if its possible to go in reverse. Is it possible to set a property on a databound item based on the state of the control its bound to?
Say I want to set the IsAlive property to true when the control its bound to receives the mouseover event.
Can this be done in WPF & data triggers? Thanks.
I don't know if what you're asking is directly possible, but I suspect it isn't. On the other hand, I think you could make your example scenario work by binding the object's "IsAlive" property directly to the control's "IsMouseOver" dependency property, with Mode=OneWayToSource.
You might want to use EventSetter, then handle the setting by code using the DataContext property of the sender, or with GetBindingExpression.
This gives you an option to set a handler on the style level.

Resources