Binding value with conditional - wpf

I'm binding a value to my DataGrid in WPF, and I would like to know how can I do something like this.
I have a int field (Category) into my model, and I would like to show a description string in my DataGrid.
Example:
The 'Category' field have this values 1,2,3,4,5 and each value has a description, how can I show the description and not the code in datagrid binding?
I've tried to create a method in my ViewModel and this method will return the string description.
//ViewModel
public string GetDescription(int pCategory)
{
if(pCategory == 1)
return "01. Description";
else if(pCategory == 2)
return "02. Description";
else if(pCategory == 3)
return "03. Description";
else
return "None";
}
//XAML DataGrid binding code
<DataGridTextColumn IsReadOnly="True" Header="Category" Binding="{Binding GetDescription(Category)}"/>

In the view use a DataGridTemplateColumn and add data triggers, something like this
<DataGridTemplateColumn>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBox>
<TextBox.Style>
<Style TargetType="TextBox">
<Setter Property="Text" Value="None"/>
<Style.Triggers>
<DataTrigger Binding="{Binding pCategory}" Value="1">
<Setter Property="Text" Value="01. Description"/>
</DataTrigger>
<DataTrigger Binding="{Binding pCategory}" Value="2">
<Setter Property="Text" Value="02. Description"/>
</DataTrigger>
<DataTrigger Binding="{Binding pCategory}" Value="3">
<Setter Property="Text" Value="03. Description"/>
</DataTrigger>
</Style.Triggers>
</Style>
</TextBox.Style>
</TextBox>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>

Related

WPF Datagrid clipboard get cell value

I need to handle the Ctrl+C function in my datagrid, especially I need to get the cell of a selected value. Here's the XAML code of the datagrid. Please note that I use DataGridTextColumn
<DataGrid x:Name="GridFormule" Grid.Row="0" BorderBrush="#abadb3" CanUserSortColumns="true" Sorting="GridFormule_Sorting" MaxColumnWidth="Infinity" Style="{DynamicResource DataGridStyle}" ColumnHeaderStyle="{DynamicResource DataGridColumnHeaderStyle}" ItemsSource="{Binding ElementName=ObjectsTree, Path=SelectedItem.Infos}" CellEditEnding="GridFormule_CellEditEnding" Margin="8,5,2,0" ContextMenu="{StaticResource cntextListe}">
<!-- OVERRIDE COPY CONTROL -->
<DataGrid.InputBindings>
<KeyBinding Key="C" Modifiers="Control" Command="Copy" />
</DataGrid.InputBindings>
<DataGrid.CommandBindings>
<CommandBinding Command="Copy" Executed="Comandi_Executed" />
</DataGrid.CommandBindings>
<!-- /OVERRIDE COPY CONTROL -->
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding Field.Formula.Formula, Mode=TwoWay}" Header="#_57_Formule" Foreground="Black" Width="*" ClipboardContentBinding="{Binding Field.Formula.Formula, Mode=TwoWay}">
<DataGridTextColumn.ElementStyle>
<Style TargetType="{x:Type TextBlock}">
<Setter Property="Padding" Value="4" />
<Setter Property="FontWeight" Value="Normal" />
<Setter Property="FontSize" Value="11.55" />
<Style.Triggers>
<DataTrigger Binding="{Binding IsDirty}" Value="True">
<Setter Property="TextBlock.Background" Value="{StaticResource IsDirtyColor}" />
<Setter Property="Padding" Value="4" />
</DataTrigger>
</Style.Triggers>
</Style>
</DataGridTextColumn.ElementStyle>
<DataGridTextColumn.EditingElementStyle>
<Style TargetType="TextBox">
<Setter Property="Background" Value="White"></Setter>
<Setter Property="Padding" Value="2,4,2,3"></Setter>
<Setter Property="BorderThickness" Value="0"></Setter>
</Style>
</DataGridTextColumn.EditingElementStyle>
</DataGridTextColumn>
</DataGridTextColumn>
</DataGrid.Columns>
</DataGrid>
The code behind to handle the copy:
private void Comandi_Executed(object sender, ExecutedRoutedEventArgs e)
{
RoutedUICommand c = (RoutedUICommand)e.Command;
switch (c.Name)
{
// Copia
case "Copy":
DataGrid sel = (sender as DataGrid);
if (sel == null) return;
if (sel.CurrentItem != null) return;
var cc = sel.CurrentColumn;
Binding binding = (Binding)cc;
// Here I get the property Name!
string BoundPropName = binding.Path.Path;
try
{
//Clipboard.SetDataObject(text);
}
catch (Exception ex)
{
Global.LOG.Log(ex.Message);
}
break;
}
}
Basically my BoundPropName returns "Field.Formula.Formula" instead of the value visible in the cell of datagrid. How can I get the cell value?

Use DataTrigger in DataGridTemplateColumn.CellStyle

I have a datagrid as follows,
<DataGrid Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="3" ItemsSource="{Binding SelectedSet.Rows}" IsSynchronizedWithCurrentItem="True" AutoGenerateColumns="False" CanUserAddRows="False" Style="{StaticResource DataGridStyle2}" HeadersVisibility="Column" SelectedItem="{Binding SelectedItem}" EnableRowVirtualization="False">
<DataGrid.Columns>
<DataGridTemplateColumn Width="30*" Header="{StaticResource RangeColumnHeader}" HeaderStyle="{StaticResource HeaderStyle2}" SortMemberPath="StartValue">
<DataGridTemplateColumn.CellStyle>
<DataTrigger Binding="{Binding SelectedSet.IsDefault}" Value="True">
<Setter Property="IsEnabled" Value="False"/>
</DataTrigger>
<DataTrigger Binding="{Binding SelectedSet.IsDefault}" Value="False">
<Setter Property="IsEnabled" Value="True"/>
</DataTrigger>
</DataGridTemplateColumn.CellStyle>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DatGrid>
I Want use " SelectedSet's " IsDefault property to set cell's IsEnabled property.
I tried above code, which is not working.
Classes are defined as follows,
public class UCSetModel : ViewModelBase
{
private Set _SelectedSet;
public Set SelectedSet
{
get
{
return _SelectedSet;
}
set
{
_SelectedSet = value;
RaisePropertyChanged("SelectedSet");
}
}
}
public class Set
{
private ObservableCollection<Markers> _rows;
public ObservableCollection<Markers> Rows
{
get
{
return _rows;
}
set
{
_rows = value;
RaisePropertyChanged("Rows");
}
}
private bool _isDefault;
public bool IsDefault
{
get
{
return _isDefault;
}
set
{
_isDefault = value;
RaisePropertyChanged("IsDefault");
}
}
}
I want to bind to a property of the same 'SelectedSet' that the rows come from.
The markup you have posted won't even compile. This does:
<DataGridTemplateColumn.CellStyle>
<Style TargetType="DataGridCell">
<Style.Triggers>
<DataTrigger Binding="{Binding IsDefault}" Value="True">
<Setter Property="IsEnabled" Value="False"/>
</DataTrigger>
</Style.Triggers>
</Style>
</DataGridTemplateColumn.CellStyle>
IsDefault is supposed to be a property of a Row object, i.e. you should remove "Set." from the binding path assuming that a row doesn't have a Set property.
If you want to bind to a property of the same SelectedSet that the rows come from, the binding should be defined like this:
<DataTrigger Binding="{Binding DataContext.SelectedSet.IsDefault, RelativeSource={RelativeSource AncestorType=DataGrid}}" Value="True">
<Setter Property="IsEnabled" Value="False"/>
</DataTrigger>
This worked for me,
<DataTrigger Binding="{Binding Path=DataContext.SelectedSet.IsDefault,ElementName=SetWindow}" Value="True">
<Setter Property="IsEnabled" Value="False"/>
</DataTrigger>

WPF - DataGrid column binding to attached property not working on context menu

I have ToggleButtons and a DataGrid, each row in DataGridColumn has a ColGroup AttachedProperty set to the name of the column group name.
Attached property:
public class DataGridColumnsGroupProperty {
public static readonly DependencyProperty ColGroupProperty =
DependencyProperty.RegisterAttached("ColGroup", typeof(object), typeof(DataGridColumnsGroupProperty), new FrameworkPropertyMetadata(null));
public static void SetColGroup(DependencyObject element, string value) {
element.SetValue(ColGroupProperty, value);
}
public static string GetColGroup(DependencyObject element) {
return (string)element.GetValue(ColGroupProperty);
}
}
The ToggleButtons has two jobs, on Check/UnCheck show/collapse all columns with the same group name.
and it has a ContextMenu which shows only the DataGridColumns with the same group name.
I've managed to bind all DataGridColumns to the ToggleButton, but couldn't find a way to Collapse the DataGridColumns with different group names.
How to fill context menu with only the columns with the givin group name inside the Style Trigger?
And how to hid all columns that has the group name when un-check toggle button?
XAML:
<ToggleButton.ContextMenu>
<ContextMenu x:Name="ContextMenu" ItemsSource="{Binding Columns, ElementName=ElementDataGrid, Converter={StaticResource TestConverter}}">
<ContextMenu.ItemContainerStyle>
<Style TargetType="MenuItem">
<Setter Property="HeaderTemplate" Value="{Binding HeaderTemplate}"/>
<Setter Property="Header" Value="{Binding Header}"/>
<Setter Property="StaysOpenOnClick" Value="True" />
<Setter Property="AutomationProperties.Name" Value="{Binding Header}"/>
<Setter Property="IsCheckable" Value="True" />
<Setter Property="IsChecked" Value="{Binding Visibility, Mode=TwoWay, Converter={StaticResource VisibilityToBooleanConverter}}" />
<Style.Triggers>
<Trigger Property="attachedProperties:DataGridColumnsGroupProperty.ColGroup" Value="FirstGroup">
<Setter Property="Visibility" Value="Collapsed" />
</Trigger>
</Style.Triggers>
</Style>
</ContextMenu.ItemContainerStyle>
</ContextMenu>
</ToggleButton.ContextMenu>
DataGridColumns:
<DataGridTextColumn x:Name="StoryCol" attachedProperties:DataGridColumnsGroupProperty.ColGroup="FirstGroup" Header="{x:Static p:Resources.Story}" IsReadOnly="True" Binding="{Binding Story}" Visibility="Visible" />
<DataGridTextColumn x:Name="CadIdCol" attachedProperties:DataGridColumnsGroupProperty.ColGroup="SecondGroup" Header="{x:Static p:Resources.CadId}" IsReadOnly="False" Binding="{Binding CadId}" Visibility="Visible" />
Using a DataTrigger should work as far as the binding to the attached property is concerned:
<DataTrigger Binding="{Binding Path=(attachedProperties:DataGridColumnsGroupProperty.ColGroup)}" Value="FirstGroup">
<Setter Property="Visibility" Value="Collapsed" />
</DataTrigger>

data trigger with enum

I have an Enum:
namespace LibiqCommonStructures
{
using System;
public enum ItemStatusType
{
NotImplemented,
New,
Processed,
Missing,
NotUsed,
Failed
}
}
<igWPF:XamDataGrid DataSource="{Binding Path=Images}" ActiveDataItem="{Binding SelectedItem}" MaxHeight="300">
<igWPF:XamDataGrid.Resources>
<Style TargetType="{x:Type igWPF:DataRecordCellArea}" BasedOn="{StaticResource {x:Type igWPF:DataRecordCellArea}}">
<Style.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Path=Record.DataItem.ItemStatus}" Value="{x:Static libIq:ItemStatusType.Missing}">
<Setter Property="Background" Value="Tomato"></Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</igWPF:XamDataGrid.Resources>
<igWPF:XamDataGrid.FieldLayoutSettings>
<igWPF:FieldLayoutSettings SelectionTypeRecord="Single" AutoGenerateFields="False" AllowDelete="False"/>
</igWPF:XamDataGrid.FieldLayoutSettings>
<igWPF:XamDataGrid.FieldSettings >
<igWPF:FieldSettings Width="Auto" AllowEdit="False" />
</igWPF:XamDataGrid.FieldSettings>
<igWPF:XamDataGrid.FieldLayouts>
I want to change the background color of the row when the enum is ItemStatusType.Missing
i can see missing the in the binding but the color of the row doesn't change.
maybe something is wrong with my x:static?
Just put the enum string in the Value. It will work:
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Path=Record.DataItem.ItemStatus}" Value="Missing">
<Setter Property="Background" Value="Tomato"></Setter>
</DataTrigger>

How do I change what shows to not match the ItemsSource in DataGrid?

I have a DataGrid with the DataContext as a list of objects with many properties.
All of the columns are bound to a different property of said object type.
There is a text property that I only care about if another bool property is set to "true" - when it is "false" I don't want the text property to show at all.
Do you have any way to suggest doing this?
I was thinking of something along the lines of:
foreach (var cur in DG.ItemsSource) {
if (!cur.BoolThatSignifiesIfICareAboutOtherProperty) {
//some code that will make the cell for cur.PropertyIMayOrMayNotCareAbout
//appear empty even though that property does have a value that the column
//is bound to
}
}
** edit **
It was suggested that I use a data trigger. So this is what I tried, but it also doesn't work. Nor does it give any errors, so I don't know what I'm doing wrong.
Here is what I have so far. It doesn't work, though. Please let me know what I'm doing wrong:
<DataGridTextColumn Header="EndDate" Binding="{Binding Path=EndDate, Converter={StaticResource DT2D}}">
<DataGridTextColumn.CellStyle>
<Style TargetType="{x:Type DataGridCell}">
<Style.Triggers>
<DataTrigger Binding="{Binding Path=DoICare}" Value="False">
<Setter Property="Content" Value=" " />
</DataTrigger>
</Style.Triggers>
</Style>
</DataGridTextColumn.CellStyle>
</DataGridTextColumn>
So this is how I solved it - I just had some of the tags wrong:
<DataGridTextColumn Header="EndDate" Binding="{Binding Path=EndDate, Converter={StaticResource DT2D}}">
<DataGridTextColumn.ElementStyle>
<Style TargetType="{x:Type TextBlock}">
<Style.Triggers>
<DataTrigger Binding="{Binding Path=DoICare}" Value="False">
<Setter Property="Visibility" Value="Hidden" />
</DataTrigger>
</Style.Triggers>
</Style>
</DataGridTextColumn.ElementStyle>
</DataGridTextColumn>

Resources