Ok this is driving me mad, I feel like a total Newbie.
I'm using WPF's DataGrid control from WPF Toolkit with .NET 3.5.
Link on Codeplex here
I want an equivalent to the classic GridView's RowDataBound event, and I can't find any. I tried working with LoadingRow, but it fires every time I scroll.
I'm trying to change the background color of certain cells in my grid based on a database values.
I'm new to WPF. Should I be using the XAML binding?
The apt way of doing that in WPF is through Datatrigger
<DataTrigger Binding="{Binding Path=State}" Value="WA">
<Setter Property="Foreground" Value="Red" />
</DataTrigger>
that comprehends to
UPDATE DataGrid
SET Foreground = 'Red'
WHERE State = 'WA';
I ended up disabling row virtualization on the DataGrid using EnableRowVirtualization="False". That way, the LoadingRow event would fire only once for all items.
Related
I've been trying to just hide items from a TreeView. I'm using a custom data type as source (called SettingsMenuItem) which inherits from FrameworkElement (currently FrameworkContentElement, because otherwise the TreeView renders them wrong).
My goal is by setting the VisibilityProperty of these FrameworkElements to either Collapsed or Visible that I'm able to hide certain items (including their children). I know that this can be done by deleting items from the source collection. But that's not what I want. It would mean that I have to mirror each collection in order to keep track of it's actual items, bind to each one in order to be notified about Visibility-changes and create a new collection each time one changes. A lot of overhead for this.
Right now I have no clue how I could accomplish that. I figure it's related to the ItemsGenerator, but I haven't seen any possibility to override it's behaviour. I thought TreeView would be able to detect Visibility, but obviously it doesn't. As alternative I thought of a custom TreeViewItem (maybe even TreeView if necessary) - but at this point the abstraction of this whole system overwhelms me. I don't know where to start and what is actually necessary to solve the problem.
Tips what I have to change or implement by myself would be more than enough. A complete solution would be nice.
You can do this using a data trigger bound to a property (e.g. "IsVisible") in you tree data nodes:
<TreeView.ItemContainerStyle>
<Style TargetType="{x:Type TreeViewItem}">
<Setter Property="Visibility" Value="Visible" />
<Style.Triggers>
<DataTrigger Binding="{Binding IsVisible}" Value="False">
<Setter Property="Visibility" Value="Collapsed" />
</DataTrigger>
</Style.Triggers>
</Style>
</TreeView.ItemContainerStyle>
While this technically answers your question I would be wary of actually doing it. User3690202's comment is correct, it's the sort of thing you would normally do via filtering in your view model.
For alternate solution using code behind xaml.cs:
To Remove a specific TreeViewItem from a TreeView which is created from a code behind.
TreeViewItem treeViewItem1 = new TreeViewItem
{
Visibility = Visibility.Collapsed,
};
use the code with TreeViewItem you want to hide in a if condition to hide specific TreeViewItem Header let say "Cars" and you want to hide it and use the code with if condition to hide "Cars" TreeViewItem.
This question already has answers here:
WPF Style DataTrigger with binding to DataContext not working
(1 answer)
Trigger based on text property not working
(1 answer)
Closed 2 years ago.
I am trying to make customizable DataGrid. I have a problem. I have researched but i couldn't find anything about it.
I created a Style for cells. In this style, there is an MultiTrigger like in the code below.
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding RelativeSource={RelativeSource Mode=Self}, Path=IsKeyboardFocusWithin}" Value="True"/>
<Condition Binding="{Binding DataContext.Tek_Satiri_Guncelleme_Modu, RelativeSource={RelativeSource AncestorType={x:Type local:DataGrid_Ozellestirilebilir}}}" Value="False"/>
</MultiDataTrigger.Conditions>
<Setter Property="BorderBrush" Value="Blue"/>
</MultiDataTrigger>
This Multitrigger works perfectly as expected like this;
This is static state -->
When cell is in focused-->
Then in C#, I change the color of cell like this.
//Get row
DataGridRow dataGridRow = (DataGridRow)DataGrid_1.ItemContainerGenerator.ContainerFromIndex(5);
//Get cell
DataGridCell cell = (DataGridCell)DataGrid_1.Columns[5].GetCellContent(dataGridRow).Parent;
cell.BorderBrush = Brushes.White; //This color i see when cell is in focus.
When i run the application this code overrides (i guess) my custom Style and i cant see Blue when the cell is in focus. I see White.
Border color turned to white as expected-->
This what i should see when cell is in focus. But i see white instead.-->
Can anyone help me about this situation?
Edit:
thatguy made very good explanation about this situation and gave two solutions. But there is a problem. This solutions work for only one color. So if I want to change the color of more than one cell, they must all be the same color. I need to adjust the colors of different cells differently. Is there any solution for this situation too?
This is caused by the precedence of a local value over a Style trigger, see the documentation.
Local value. A local value might be set through the convenience of the "wrapper" property, which also equates to setting as an attribute or property element in XAML, [...]
Style triggers. The triggers within styles from page or application (these styles might be either explicit or implicit styles, but not from the default styles, which have lower precedence).
To solve this problem, you could use one of the following options.
Try to integrate the White color with additional triggers into your existing style
Create another style based on your current style and add a setter for the color White and assign this style to the cells that need to be styled differently
<Style x:Key="MySpecialCellStyle" BasedOn="{StaticResource MyCellStyle}" TargetType="{x:Type DataGridCell}">
<Setter Property="BorderBrush" Value="White"/>
</Style>
cell.Style = (Style)FindResource("MySpecialCellStyle");
I have this XAML in my RadDataGrid that changes the background color of a selected row to red based on the value returned by the ValidateModuleBank property defined in my model.
<tg:RadDataGrid.Resources>
<Style TargetType="gridPrimitives:SelectionRegionBackgroundControl">
<Setter Property="Background" Value="{Binding ValidateModuleBank,Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
</Style>
</tg:RadDataGrid.Resources>
I looked online and it says that UWP does not support binding to a property in a style. So, how can I achieve this?
Thanks in advance for your help.
I’m working on a WPF/PRISM app. I started by creating a dynamic menu using databinding following that example: http://www.koaxkoaxkoax.com/ribbit/2010/09/creating-dynamic-menus-in-wpf.html
It uses a HierarchicalDataTemplate which seems like a nice solution.
I had the goal to use the same concept for toolbars but sadly the ToolBarTray control doesn’t have a ItemsSource to dynamically generate Toolbar controls in it.
I’m pretty new to WPF and I can’t seem to find a good solution to create toolbars inside a ToolBarTray using databinding. Does somebody have a solution?
Is it possible with HierarchicalDataTemplate?
Thank you
While the ToolBarTray does not contain an ItemsSource property, it does contain a ToolBars property that you'd be able to bind to. And then, each ToolBar has an ItemsSource property that you could bind to as well.
So your binding would look something like this:
<ToolBarTray ToolBars="{Binding MyToolBarsProperty}" />
Then you could start using HierarchicalDataTemplates on the Toolbars:
<HierarchicalDataTemplate.ItemContainerStyle>
<Style TargetType="Button">
<Setter Property="Command" Value="{Binding Command}"/>
</Style>
</HierarchicalDataTemplate.ItemContainerStyle>
I have a ListBox that when in focus, and when I have an item selected returns a valid SelectedIndex. If I have a valid SelectedIndex and I click on a TextBox on the same Forum, the SelectedIndex now becomes -1. However I want it to keep its SelectedIndex from changing. How would I go about doing this?
ListBox will keep it's SelectedIndex regardless of focus.
I tested it on a blank project with one ListBox, one TextBox and one Label used to display the ListBox's SelectedIndex. Under both the ListBox's SelectedIndexChanged and the TextBox's TextChanged events I updated the Label with the ListBox's SelectedIndex
There must be something else going on to cause the Selected Index to change to -1.
I had the same issue as original poster.
I couldn't figure it out totally but it seems like when you have the listbox bound to an observable collection and the collection gets changed that the selected item loses the focus.
I hacked around the issue by saving the selected index in a variable and resetting it if the selected index was -1 (and it was valid to restore it)
This is an old question, but in case someone else experiences the same problem check your ListBoxItem style especially if you are using one of styles from WPF Themes.
The problem with WPF Themes specifically is the inclusion of the
section outside of the Control Template:
<Style d:IsControlPart="True" TargetType="{x:Type ListBoxItem}">
....
<Style.Triggers>
<Trigger Property="Selector.IsSelected" Value="True">
<Setter Property="Foreground">
<Setter.Value>
<SolidColorBrush po:Freeze="True" Color="{DynamicResource BlackColor}" />
</Setter.Value>
</Setter>
</Trigger>
<Trigger Property="IsKeyboardFocusWithin" Value="true">
<Setter Property="IsSelected" Value="true" />
</Trigger>
</Style.Triggers>
</Style>
Delete the Style.Triggers and the problem should go away
Handle the SelectedIndexChanged event and save the selected value so that you can restore it when your control regains focus.
I haven't verified this in my apps but if the SelectedIndex property changes when the LB loses focus you probably have to handle that case yourself by caching the last selected index and resetting it when the control regains focus. You can do this in the containing form or you can do it in a class derived from ListBox.
You could even try setting the selected index as soon as you see it becomes -1. Not sure what would happen but I'd be curious to find out....
Edit: just tested it and like the other poster I can't reproduce it either. Must be something slightly different about your LB
Are these controls in different dialogs, or maybe different tabs on a tabbed container? That's the only way I can think of that you would lose your SelectedIndex when changing focus. Otherwise, how would anybody e.g. click a button to take action on an item? You'd lose the selection when focus went to the button you're clicking...