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
Related
I want to make a style for fields of XamDataGrid to set the AllowEdit property of the fields in the converter using some conditions.
I am trying with this but not working for me.
<Style TargetType="{x:Type igWPF:Field}">
<Style.Setters>
<Setter Property="AllowEdit" Value="{Binding Path=Field, Source={RelativeSource Self}, Converter={StaticResource FieldsEditableConverter}}">
</Setter>
</Style.Setters>
</Style>
Please suggest some code.
Infragistics said : "Once WPF Styles are in use, you cannot modify them."
Since I was looking for slightly the same thing (XamDataGrid, Field, Style, Setter modification of just access setter programmatically) but I wasn't able to. I've found the following information :
This exception has nothing to do with Infragistics controls. Once WPF Styles are in use, you cannot modify them. If you want to programmatically create Styles, you should create them from scratch, and not try to modify existing Style objects.
http://www.infragistics.com/community/forums/t/13909.aspx
Despite the fact that you can not modify it dynamically, so, on my specific case, I finally used x:Name of Style used by the targeted setter when required : so just before it has to modify the list (CanExecute).
This is how my code looks like :
C# :
var cm = uc.Resources["fiContextMenu"] as ContextMenu;
foreach(MenuItem mi in cm.Items)
if(mi.Header.Equals("Remove File"))
mi.IsEnabled = false; //Disallow remove when empty list
Xaml :
<igDP:FieldSettings.EditorStyle>
<Style TargetType="{x:Type igEditors:XamComboEditor}">
<Setter Property="ContextMenu" Value="{StaticResource fiContextMenu}" />
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.
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...
Are there any slick ways to style/template a WPF ItemsControl differently based off whether ItemsSource holds a single value or multiple values?
What I've done so far is to create a custom ItemsControl class which among other things displays the list of bound items as a horizontally oriented comma separated list. So far I'm pretty happy with the results however I want to show a more brief view of the bound data in cases where multiple values are bound and if only a single value is bound then I want to show a more extended view of the bound data with a longer string description. I figure this is probably best solved by dynamically choosing the template either based off a trigger or possibly by using a template selector but it's not yet clear to me how this would be done.
You could use a DataTrigger in your style to replace the template:
<Style.Triggers>
<DataTrigger Binding="{Binding RelativeSource={x:Static RelativeSource.Self}, Path=Items.Count}" Value="1">
<Setter Property="Template">
<Setter.Value>
<!-- Insert Template here -->
</Setter.Value>
</Setter>
</DataTrigger>
</Style.Triggers>
You could also add one for where the Value is 0 if you wanted to display a "no records" template.
You should use a StyleSelector.
Here is a sample.
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.