Change FontWeight of specific row of DevExpress GridControl in WPF - c#

I want to Change the FontWeight of a specific row to bold. So i have a DataTable (MyDataTable):
Name Location
-------------------
Mark New-York
Julian Paris
Donald Moscow
which i bind to a DevExpress GridControl
<dxg:GridControl ItemsSource="{Binding MyDataTable}">
Now i would like to Change the FontWeight of the row where the Name is 'Julian'. How can i do this?
I thought using a DataTrigger like:
<dxg:GridControl.Resources>
<Style TargetType="{x:Type dxg:GridRow}">
<Style.Triggers>
<DataTrigger Binding="{Binding MyDataTable.Columns[0]}" Value="Name">
<Setter Property="FontWeight" Value="Bold"/>
</DataTrigger>
</Style.Triggers>
</Style>
</dxg:GridControl.Resources>
but this is not working. I tried several other Options, but did not find a working solution. Can someone please guide me in the right direction? I would very much prefer to do it directly in xaml and not in code behind, if this is possible.

Use FormatConditions Property to format row or cell with condition
<dxg:TableView.FormatConditions> <dxg:FormatCondition Expression="[Name] = 'Julian'" FieldName="Name" />
EDIT:
If you want formatting in code - Formatting in Code

Related

Assigning color in C# overrides Style. How can I prevent this? [duplicate]

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");

How to make part of TreeViewItem Header bold?

I am trying to implement a simple search feature in SQL and wpf... I need to highlight only part of the next in results that has been entered in a TextBox.
So I do the search in SQL get the results and put them on a TreeViewItem that adds them to a TreeView. That all works but how would i go around making only a certain part of TreeViewItem Header bold?
I already know how to find where the part of the text I want bold is but i just need to make it bold.
TreeViewItem root_item = new TreeViewItem() { Header = "Users" };
FoundUsersTreeView.Items.Add(root_item);
while (sqlReader.Read())
{
TreeViewItem new_item = new TreeViewItem() { Header = sqlReader.GetString(0) };
root_item.Items.Add(new_item);
}
If you're going to use wpf for any substantial work, you should use MVVM.
Working directly with controls is OK for very simple stuff but the difficulty ramps up very quickly.
You should Bind data and template that into controls instead.
This is how WPF is intended to be used.
Work with the base data rather than controls.
If you take a look at this sample:
https://gallery.technet.microsoft.com/WPF-Highlight-Matching-71ad5a04
It works with a listview rather than treeview and highlights text by making the background red.
Not exactly what you need.
But the principle is the thing to look at.
You could easily change the listview used to a treeview.
Having said that, you only seem to have on level of items in your treeview, so you pretty much might as well use a listview anyhow.
Anyhow.
If you take a look, you'll see each item is split up using a regex so there's a separate RunHi viewmodel for each piece.
Matching pieces have IsMatch set to true on their RunHi.
These are templated into a horizontal listview - so it looks like one textblock but is in fact one or more arranged one after the other.
Each row of the listview is itself a listview.
You could of course make the header of each treeviewitem a listview if you particularly want a treeview.
A datatrigger is used to make the background yellow.
To make it bold instead you can just change that part:
<ControlTemplate TargetType="{x:Type ListViewItem}">
<TextBlock Text="{Binding Text}">
<TextBlock.Style>
<Style TargetType="TextBlock">
<Style.Triggers>
<DataTrigger Binding="{Binding IsMatch}" Value="True">
<Setter Property="FontWeight" Value="Bold"/>
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
</ControlTemplate>
You can achieve this using HeaderTemplate of your TreeViewItem. As you're adding TreeViewItem from code behind, you can use the Tag property to differentiate which one need to be set as Bold.
You can add below DataTemplate to your Resources.
DataTemplate
<DataTemplate x:Key="headerTemplate">
<TextBlock Text="{Binding}">
<TextBlock.Style>
<Style TargetType="TextBlock">
<Style.Triggers>
<DataTrigger Binding="{Binding Tag, RelativeSource={RelativeSource AncestorType=TreeViewItem, Mode=FindAncestor}}"
Value="True">
<Setter Property="FontWeight" Value="Bold"/>
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
</DataTemplate>
Code Behind
TreeViewItem root_item = new TreeViewItem() { Header = "Users" };
treeView.Items.Add(root_item);
while (sqlReader.Read())
{
var new_item = new TreeViewItem { Header = sqlReader.GetString(0), Tag = true };
new_item.HeaderTemplate = Resources["headerTemplate"] as DataTemplate;
root_item.Items.Add(new_item);
}
You can set boolean value to Tag property to make that Node as Bold.

Apply dynamic value to Setter property in UWP RadDataGrid

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.

Display grid with dynamic columns and cell backgrounds

I've tried many options, but none seem to work fine for me. Here is the problem:
Dynamic columns. I get a list of dictionaries. All dictionaries may have different keys.
E.g.
[ [key1: 111], [key2: 222] ]
[ [key1: 333], [key4: 444] ]
[ [key5: 777] ]
I need to display a grid with all keys as columns like this:
[key1] [key2] [key4] [key5]
111 222
333 444
777
This is pretty easy, I just generate columns in code either for GridView or DataGrid.
But there is a second requirement:
I need to color particular cells depending on value in them.
E.g. for 111 bg color should be green, for 333 it should be red etc.
Currently I can only make one part work. I can dynamically create columns, but then I can't color them. Or I can create static columns and create custom cell templates with bindings for bg colors. But, then in every template I have to specify the binding. So the number of templates will be big.
Is there a way to achive what I need, without generating template for each column?
Personally I would like to avoid generating templates in code.
Not sure I understand your problem completely, but it should be quite simple. DataGrid is amazingly flexible.
You almost have it, as far I understand. Now you want one global CellTemplate that can be obtained from XAML resources(so you don't hardcode it into code).
The CellTemplate can change colors based on triggers. You can either hardcode it into XAML or provide Dictionary that can map from "VALUE" to "COLOR" and just bind CellTemplate's Background to that Dictionary.
When you generate dynamically columns, you set DataGridTextColumn.CellTemplate to LoadDynamicallyXaml("yourresource"). When you generate columns, you have access to your DataGrid Resources, and you can obtain the CellTemplate from there too, that's cleaner way.
Loading XAML at runtime?
You can define a Style for a TextBlock that contains your DataTriggers and then just apply that Style to a TextBlock in your dynamically created columns... this method should be good for up to around 8 different value/colour pairs before the code gets too long:
<Style TargetType="{x:Type TextBlock}">
<Style.Triggers>
<DataTrigger Binding="{Binding}" Value="111">
<Setter Property="TextElement.Foreground" Value="LightGreen" />
</DataTrigger>
<DataTrigger Binding="{Binding}" Value="222">
<Setter Property="TextElement.Foreground" Value="LightBlue" />
</DataTrigger>
<DataTrigger Binding="{Binding}" Value="333">
<Setter Property="TextElement.Foreground" Value="LightPink" />
</DataTrigger>
</Style.Triggers>
</Style>
The other method that you can use is to use a Converter class with your Binding. You can find a detailed example of doing this in many online posts... here are a few:
How to set Foreground of DataGrid Column with ValueConverter
Datagrid AutoGenerateColumns="True" forecolor IValueConverter

How to create different ItemsPanelTemplate for a ListBox

I'm writing an IM program on Windows Phone 8. And I am currently dealing with the UI for chatting.
I want to create a ListBox that holds all the "chat bubbles" (like those in iPhone). The incoming messages appear on the left-hand side, and outgoing messages on the right-hand side. Like this:
So obviously, I need to set differnt alignment for each item.
I was trying to solve this by wrapping the bubble in a large Grid that expands all the space in the ItemsPanel, and align the chat bubble to the right (the parent of the chat bubble is the large Grid). But that didn't work because a grid in ItemsPanel won't fill up all the spaces automatically. And then I went for searching "how to fill up all spaces in ItemsPanel" and no luck.
So, I think the only way to do this is to set different ItemsPanelTemplate for each ItemsPanel, to either "Right" or "Left".
Please, help me.. Thank you!
So how do you create a selector for different ItemsPanelTemplate?
You just need to customize the itemContainer :
<ItemsControl.ItemContainerStyle>
<Style TargetType="ContentPresenter">
<Style.Triggers>
<DataTrigger Binding="{Binding IsAnswer}" Value="True">
<Setter Property="HorizontalAlignment" Value="Right"/>
</DataTrigger>
</Style.Triggers>
</Style>
</ItemsControl.ItemContainerStyle>
In case you dont have style triggers, you can use binding and a bool to HorizontalAlignment converter :
<ItemsControl.ItemContainerStyle>
<Style TargetType="ContentPresenter">
<Setter Property="HorizontalAlignment" Value="{Binding IsAnswer,Converter={StaticResource AlignmentConverter}}"/>
</Style>
</ItemsControl.ItemContainerStyle>
you only need 2 View's for your messages aka DataTemplate
one for MyMsg and one for Answer both inhire from the Message class or interface (your decision) lets call it Msg
so you can set your ItemsSource to List<Msg> or ObservableCollection<Msg> and you are done

Categories