Several combo boxes in one DataGrid - c#

I'm trying to bind combobox with different values in each row to DataGrid. My problem is most likely that I do not know how to set ItemsSource and SelectedValuePath. How should it be done?
.cs:
private List<List<ComboItem>> ComboBoxItemsList = new List<List<ComboItem>>();
...
foreach (AppSettingsElement list in enablers[key])
{
string[] stringSeparators = new string[] { "\r\n" };
string[] lines = list.Comment.Split(stringSeparators, StringSplitOptions.None);
List<ComboItem0> comboItems = GetComboItemList(lines);
// clean comment
list.Comment = lines[1];
//add to comboList
appSettingsComboBoxList.Add(new AppSettingsElement {Comment=list.Comment, Name= list.Name, Value=list.Value, ComboItems = comboItems });
}
AppSettingsDropDowns.ItemsSource = appSettingsComboBoxList;
...
public class ComboItem0
{
public string ID { get; set; }
public string Text { get; set; }
}
public class AppSettingsElement : ComboItem0
{
public string Comment { get; set; }
public string Name { get; set; }
public string Value { get; set; }
public string Type { get; set; }
public List<ComboItem0> ComboItems { get; set; }
}
.xaml:
<DataGrid x:Name="AppSettingsDropDowns" AutoGenerateColumns="False" Grid.ColumnSpan="6" Grid.Row="8" CanUserAddRows="False" >
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding Comment}" Header="Comment" Width="4*" IsReadOnly="True" />
<DataGridTextColumn Binding="{Binding Name}" Header="Element Name" Width="*" IsReadOnly="True"/>
<DataGridComboBoxColumn ItemsSource="{Binding ComboItems}" SelectedValueBinding="{Binding Value}" SelectedValuePath="ID" DisplayMemberPath="Text" Header="Value" Width="*" />
</DataGrid.Columns>
</DataGrid>
EDIT: My code currently displays blank selection of combo boxes.

<DataGrid x:Name="AppSettingsDropDowns" AutoGenerateColumns="False" Grid.ColumnSpan="6" Grid.Row="8" CanUserAddRows="False" >
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding Comment}" Header="Comment" Width="4*" IsReadOnly="True" />
<DataGridTextColumn Binding="{Binding Name}" Header="Element Name" Width="*" IsReadOnly="True"/>
<DataGridComboBoxColumn DisplayMemberPath="Text" SelectedValuePath="ID" Header="Value" Width="*" >
<DataGridComboBoxColumn.ElementStyle>
<Style TargetType="{x:Type ComboBox}">
<Setter Property="ItemsSource" Value="{Binding ComboItems}"/>
<Setter Property="SelectedValue" Value="{Binding Value}" />
</Style>
</DataGridComboBoxColumn.ElementStyle>
<DataGridComboBoxColumn.EditingElementStyle>
<Style TargetType="{x:Type ComboBox}">
<Setter Property="ItemsSource" Value="{Binding ComboItems}"/>
<Setter Property="SelectedValue" Value="{Binding Value}" />
</Style>
</DataGridComboBoxColumn.EditingElementStyle>
</DataGridComboBoxColumn>
</DataGrid.Columns>
</DataGrid>

Related

new row in datagrid with custom data

I have two datagrids. The first one is an overview about a time tracking. The second one shows some details.
For example:
The first datagrid contains each day, where a employee works. The second datagrid contains the time stamping for a day.
However, when I add a new stamping row, the controls in the datagrid are empty. That is not really a problem but the datepicker shows the date 01/01/0001.
what i want is when i add a new row, the date field should be filled with the date from the first datagrid.
VIEW:
<DataGrid Grid.Column="0"
IsReadOnly="True"
AutoGenerateColumns="False"
Grid.Row="0"
x:Name="DgStundenView"
Margin="0 0 10 0"
SelectedItem="{Binding SelectedItem}"
ItemsSource="{Binding TimeOverviewList}">
<DataGrid.Columns>
<DataGridTextColumn Header="Wochentag" Binding="{Binding Wochentag}" />
<DataGridTextColumn Header="Datum" Binding="{Binding Tag}" />
<DataGridTextColumn Header="Arbeitszeit Soll" Binding="{Binding ArbeitszeitInStunden}" />
<DataGridTextColumn Header="Arbeitszeit gesamt" Binding="{Binding GesamtDauerInStunden}" />
<DataGridTextColumn Header="Pausenzeit" Binding="{Binding Pausenzeit}" />
<DataGridTextColumn Header="Pausendifferenz" Binding="{Binding PausenDifferenzInStunden}" />
<DataGridTextColumn Header="Arbeitszeit inkl. Pause" Binding="{Binding TatsaechlicheDauerInStunden}" />
<DataGridCheckBoxColumn Header="Status" Binding="{Binding StempelungVorhanden,Mode=OneWay}" />
<DataGridTextColumn Header="Info" Binding="{Binding Info}" />
</DataGrid.Columns>
<DataGrid.RowStyle>
<Style TargetType="DataGridRow">
<Style.Triggers>
<DataTrigger Binding="{Binding Wochentag}" Value="Sa">
<Setter Property="Background" Value="LightGray" />
</DataTrigger>
<DataTrigger Binding="{Binding Wochentag}" Value="So">
<Setter Property="Background" Value="LightGray" />
</DataTrigger>
</Style.Triggers>
</Style>
</DataGrid.RowStyle>
</DataGrid>
<DataGrid Grid.Column="0"
Grid.Row="1"
x:Name="DgStempelungen"
Margin="0 10 10 0"
AutoGenerateColumns="False"
CanUserAddRows="True"
SelectedItem="{Binding SelectedValue}"
ItemsSource="{Binding TimeDetailList}">
<DataGrid.Resources>
<x:Array x:Key="Reasons" Type="system:String">
<system:String>NICHT ANWENDBAR</system:String>
<system:String>KRANK</system:String>
<system:String>GANZER TAG URLAUB</system:String>
</x:Array>
</DataGrid.Resources>
<DataGrid.Columns>
<DataGridTextColumn Header="ID" IsReadOnly="True" Binding="{Binding Id}"/>
<DataGridTemplateColumn Header="KOMMEN DATUM">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<DatePicker SelectedDate="{Binding ComeBooking}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Header="KOMMEN UHRZEIT">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<materialDesign:TimePicker Text="{Binding ComeBookingTime, StringFormat=t}"
Is24Hours="True">
</materialDesign:TimePicker>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Header="GEHEN DATUM">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<DatePicker SelectedDate="{Binding GoBooking}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Header="GEHEN UHRZEIT">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<materialDesign:TimePicker Text="{Binding GoBookingTime, StringFormat=t}"
Is24Hours="True">
</materialDesign:TimePicker>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridComboBoxColumn Header="GRUND"
ItemsSource="{StaticResource Reasons}"
TextBinding="{Binding Info}"/>
</DataGrid.Columns>
</DataGrid>
VIEW MODEL
[CanBeNull] private ClassTimeTrackingDayStamp _selectedItem;
[CanBeNull]
public ClassTimeTrackingDayStamp SelectedItem
{
get { return _selectedItem; }
set
{
_selectedItem = value;
OnPropertyChanged();
if (_selectedItem != null)
TimeDetailList = new ObservableCollection<ClassTimeTrackingTimeStamp>(_selectedItem.Stempelungen);
}
}
private ObservableCollection<ClassTimeTrackingDayStamp> _timeOverviewList;
public ObservableCollection<ClassTimeTrackingDayStamp> TimeOverviewList
{
get { return _timeOverviewList; }
set
{
_timeOverviewList = value;
OnPropertyChanged();
}
}
[CanBeNull] private ObservableCollection<ClassTimeTrackingTimeStamp> _timeDetailList;
[CanBeNull]
public ObservableCollection<ClassTimeTrackingTimeStamp> TimeDetailList
{
get { return _timeDetailList; }
set
{
_timeDetailList = value;
OnPropertyChanged();
}
}
MODEL
public class ClassTimeTrackingTimeStamp : ViewModelBase
{
public DateTime ComeBooking { get; set; }
public DateTime GoBooking { get; set; }
public TimeSpan ComeBookingTime { get; set; }
public TimeSpan GoBookingTime { get; set; }
public int Id { get; set; }
public string Info { get; set; }
}
Update
EVENT OVER MVVM VIEW
<DataGrid Grid.Column="0"
Grid.Row="1"
x:Name="DgStempelungen"
Margin="0 10 10 0"
AutoGenerateColumns="False"
CanUserAddRows="True"
SelectedItem="{Binding SelectedValue}"
ItemsSource="{Binding TimeDetailList}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="AddingNewItem">
<i:InvokeCommandAction Command="{Binding Path=AddNewItemCommand}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
...
VIEW MODEL
public ICommand AddNewItemCommand { get; set; }
#endregion Properties
#region Events
public event EventHandler AddNewItemEventHandler;
#endregion
#region Constructor
public WTimeClockOverviewVM()
{
AddNewItemCommand = new RelayCommand(o =>
{
this.AddNewItemEventHandler?.Invoke(this, EventArgs.Empty);
});
}
CODE BEHIND
public WTimeClockOverview()
{
InitializeComponent();
var vm = (WTimeClockOverviewVM)DataContext;
if(vm == null) return;
vm.AddNewItemEventHandler += (sender, args) =>
{
var selectedItemInFirstDg = vm.SelectedItem;
if (selectedItemInFirstDg != null)
{
var newItem = new ClassTimeTrackingTimeStamp();
newItem.ComeBooking = selectedItemInFirstDg.Tag;
}
};
}
Thank you for your help :)
Best regards
Levin
In second DataGrid, you can subscribe to AddingNewItem event
<DataGrid x:Name="DgStempelungen"
AddingNewItem="DgStempelungen_OnAddingNewItem"
...
In code behind
private void DgStempelungen_OnAddingNewItem(object sender, AddingNewItemEventArgs e)
{
// I'll assume that the Model's Name in first DataGrid collection is StudentItem!
var selectedItemInFirstDg = DgStundenView.SelectedItem as StudentItem;
// or you can get the selected item from the DataContext:
// (DgStundenView.DataContext as MyViewModel)?.SelectedItem;
if (selectedItemInFirstDg != null){
// create the new row with data from selectedItemInFirstDg, ex. date, etc...
e.NewItem = new ClassTimeTrackingDayStamp
{
ComeBooking = selectedItemInFirstDg.Date; // for example
};
}
}

How to set selected items in MVVM using SelectionMode="Extended"?

Goal
I currently have an app that select the items only by selecting the check box. Like so:
My goal is to multi select items (Which highlights the selected rows), right click and have a data context menu item to select, selected items.
Desired Output
As an example, this would be my desired output (Obviously not selecting the checkboxes manually).
Question
What would a good starting point to achieve this output? I couldn't find any examples.
Code
The Model is pretty simple.
public class OrdersModel : BaseVM
{
public int OrderId { get; set; } // Hidden
public string OrderNumber { get; set; }
public DateTime OrderDate { get; set; }
private bool _selectedRecord;
public bool SelectedRecord
{
get { return _selectedRecord; }
set
{
_selectedRecord = value;
OnPropertyChanged();
}
}
}
And this is my current XAML.
<DataGrid ItemsSource="{Binding Orders}"
AutoGenerateColumns="False"
SelectionMode="Extended"
CanUserAddRows="False">
<DataGrid.RowStyle>
<Style TargetType="DataGridRow">
<Style.Triggers>
<DataTrigger Binding="{Binding Path=SelectedRecord}" Value="True">
<Setter Property="Background" Value="LightGray" />
</DataTrigger>
</Style.Triggers>
</Style>
</DataGrid.RowStyle>
<!--Columns Used-->
<DataGrid.Columns>
<!--Select All Column-->
<DataGridTemplateColumn>
<DataGridTemplateColumn.HeaderTemplate>
<DataTemplate>
<CheckBox Content="Select All"
IsChecked="{Binding DataContext.SelectAll, RelativeSource={RelativeSource FindAncestor, AncestorType=DataGrid}}"
Command="{Binding DataContext.ToggleAllOrdersCommand, RelativeSource={RelativeSource FindAncestor, AncestorType=DataGrid}}"/>
</DataTemplate>
</DataGridTemplateColumn.HeaderTemplate>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<CheckBox IsChecked="{Binding Path=SelectedRecord, UpdateSourceTrigger=PropertyChanged}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTextColumn Header="Order Date"
Binding="{Binding OrderDate, StringFormat='{}{0:MM-dd-yyyy}'}" Width="*"
IsReadOnly="True"
FontSize="14" />
<DataGridTextColumn Header="Order Number"
Binding="{Binding OrderNumber}" Width="*"
IsReadOnly="True"
FontSize="14" />
</DataGrid.Columns>
<!--Menu Options-->
<DataGrid.ContextMenu>
<ContextMenu>
<MenuItem Header="Select Highlighted Rows" />
</ContextMenu>
</DataGrid.ContextMenu>
</DataGrid>
This solution worked for me. I took the liberty of changing some of your property names to avoid confusion as to what is "selected" and what is "checked".
OrdersModel:
public class OrdersModel : BaseVM
{
public int OrderId { get; set; } // Hidden
public string OrderNumber { get; set; }
public DateTime OrderDate { get; set; }
private bool _selected;
private bool _checked;
public bool Selected
{
get { return _selected; }
set { _selected = value; OnPropertyChanged(); }
}
public bool Checked
{
get { return _checked; }
set { _checked = value; OnPropertyChanged(); }
}
}
MainWindow.xaml.cs
<DataGrid ItemsSource="{Binding Orders}"
AutoGenerateColumns="False"
SelectionMode="Extended"
CanUserAddRows="False"
Tag="{Binding ElementName=myWindow,Path=DataContext}"
>
<DataGrid.RowStyle>
<Style TargetType="DataGridRow">
<Setter Property="IsSelected" Value="{Binding Selected}"/>
<Style.Triggers>
<DataTrigger Binding="{Binding Path=Selected}" Value="True">
<Setter Property="Background" Value="LightGray" />
</DataTrigger>
</Style.Triggers>
</Style>
</DataGrid.RowStyle>
<!--Columns Used-->
<DataGrid.Columns>
<!--Select All Column-->
<DataGridTemplateColumn>
<DataGridTemplateColumn.HeaderTemplate>
<DataTemplate>
<CheckBox Content="Select All"
IsChecked="{Binding DataContext.SelectAll, RelativeSource={RelativeSource FindAncestor, AncestorType=DataGrid}}"
Command="{Binding DataContext.ToggleAllOrdersCommand, RelativeSource={RelativeSource FindAncestor, AncestorType=DataGrid}}"/>
</DataTemplate>
</DataGridTemplateColumn.HeaderTemplate>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<CheckBox IsChecked="{Binding Path=Checked, UpdateSourceTrigger=PropertyChanged}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTextColumn Header="Order Date"
Binding="{Binding OrderDate, StringFormat='{}{0:MM-dd-yyyy}'}" Width="*"
IsReadOnly="True"
FontSize="14" />
<DataGridTextColumn Header="Order Number"
Binding="{Binding OrderNumber}" Width="*"
IsReadOnly="True"
FontSize="14" />
</DataGrid.Columns>
<!--Menu Options-->
<DataGrid.ContextMenu>
<ContextMenu DataContext="{Binding Path=PlacementTarget.Tag, RelativeSource={RelativeSource Self}}">
<MenuItem Header="Select Highlighted Rows" Command="{Binding CheckSelectedCommand}"/>
</ContextMenu>
</DataGrid.ContextMenu>
</DataGrid>
MainWindow.xaml.cs:
public class MainWindowViewModel : BaseVM
{
private ObservableCollection<OrdersModel> _orders;
private RelayCommand _checkSelectedCommand;
public MainWindowViewModel()
{
Initialize();
}
public ObservableCollection<OrdersModel> Orders
{
get
{
if (_orders == null)
_orders = new ObservableCollection<OrdersModel>();
return _orders;
}
}
public RelayCommand CheckSelectedCommand
{
get
{
if (_checkSelectedCommand == null)
_checkSelectedCommand = new RelayCommand(o => DoCheckSelectedRows());
return _checkSelectedCommand;
}
}
public void Initialize()
{
var dateTime = DateTime.Now.AddDays(-5);
for (int i = 0; i < 10; i++)
{
this.Orders.Add(new OrdersModel() { OrderId = i, OrderDate = dateTime.AddHours(4), OrderNumber = $"CA{i + 1593:0000}" });
}
}
private void DoCheckSelectedRows()
{
var selectedOrders = this.Orders.Where(o => o.Selected);
foreach (var order in selectedOrders)
{
order.Checked = true;
}
}
}
Solution will look like this:

WPF DataGrid different controls in the same column - incorrect binding

I am developing the application which performs checks on the list of items. Each item has the list of the checks that need to be performed on it. Each check can be one of 3 types: CheckBox, ComboBox, TextBox.
I would like to have Datagrid with 2 columns (one for item name, second for list of checks). Second column contains another DataGrid with 2 columns (one for check name, second for check control). The purpose is to have different types of controls in the same column bound with the Check models.
The problem is that binding with CheckValue doesn't work, however bindings with all the other properties work fine.
The last column contains CheckBoxes, TextBox and ComboBox, however they are not filled with any values.
Does anyone know what is wrong with below code?
Here are examples of model classes
public class Item
{
public string ItemName { get; set; }
public ObservableCollection<Check> Checks { get; set; }
public Item()
{
Checks = new ObservableCollection<Check>();
}
}
public enum CheckType
{
CheckBox,
ComboBox,
TextBox
}
public abstract class Check
{
public string CheckName { get; set; }
public CheckType CheckType { get; protected set; }
public abstract object CheckValue { get; set; }
}
public class CheckBox : Check
{
private bool checkValue;
public CheckBox()
{
CheckType = CheckType.CheckBox;
}
public override object CheckValue
{
get
{
return checkValue;
}
set
{
checkValue = (bool)value;
}
}
}
public class ComboBox : Check
{
private List<string> checkValue;
public ComboBox()
{
CheckType = CheckType.ComboBox;
}
public override object CheckValue
{
get
{
return checkValue;
}
set
{
checkValue = value as List<string>;
}
}
}
public class TextBox : Check
{
private string checkValue;
public TextBox()
{
CheckType = CheckType.TextBox;
}
public override object CheckValue
{
get
{
return checkValue;
}
set
{
checkValue = value as string;
}
}
}
public class MainViewModel
{
public ObservableCollection<Item> Items { get; set; }
public MainViewModel()
{
Items = new ObservableCollection<Item>();
Item item = new Item();
item.ItemName = "First item";
Check check1 = new CheckBox() { CheckName = "Check 1", CheckValue = true };
Check check2 = new CheckBox() { CheckName = "Check 2", CheckValue = false };
Check text1 = new TextBox() { CheckName = "Check 3", CheckValue = "Please enter check" };
Check combo1 = new ComboBox() { CheckName = "Check 4", CheckValue = new List<string> { "Value1", "Value2" } };
item.Checks.Add(check1);
item.Checks.Add(check2);
item.Checks.Add(text1);
item.Checks.Add(combo1);
Items.Add(item);
}
}
And finally here is XAML code of the main window.
<Window x:Class="ItemTest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vm ="clr-namespace:ItemTest"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<vm:MainViewModel x:Key="mainViewModel"/>
</Window.Resources>
<Grid DataContext="{Binding Source={StaticResource mainViewModel}}">
<DataGrid ItemsSource="{Binding Path=Items}" AutoGenerateColumns="False">
<DataGrid.Columns>
<DataGridTextColumn Header="Item" Binding="{Binding ItemName}" />
<DataGridTemplateColumn Header="Checks">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<DataGrid ItemsSource="{Binding Checks}" AutoGenerateColumns="False" HeadersVisibility="None">
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding CheckName}" />
<DataGridTemplateColumn>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ContentControl>
<ContentControl.Style>
<Style TargetType="ContentControl">
<Style.Triggers>
<DataTrigger Binding="{Binding CheckType}" Value="CheckBox">
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<CheckBox IsChecked="{Binding CheckValue}"/>
</DataTemplate>
</Setter.Value>
</Setter>
</DataTrigger>
<DataTrigger Binding="{Binding CheckType}" Value="ComboBox">
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<ComboBox ItemsSource="{Binding CheckValue}" />
</DataTemplate>
</Setter.Value>
</Setter>
</DataTrigger>
<DataTrigger Binding="{Binding CheckType}" Value="TextBox">
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<TextBox Text="{Binding CheckValue}" />
</DataTemplate>
</Setter.Value>
</Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</ContentControl.Style>
</ContentControl>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
</Grid>
Just set the ItemControl's Content property:
<ContentControl Content="{Binding}">
WPF will automatically set DataTemplate's DataContext to its parent ContentControl's Content. But in your XAML you don't set the Content property (you only specify ContentControl's Style, but forget to set its Content).
And don't forget to set UpdateSourceTrigger=PropertyChanged on your control bindings, otherwise you may see no updates in your viewmodel.
XAML example working, with binding for BindingList :
<DataGrid x:Name="dataGridParametros"
Grid.Row="1"
Margin="5"
AutoGenerateColumns="False"
HeadersVisibility="All"
ItemsSource="{Binding}"
RowHeaderWidth="20"
SelectionUnit="FullRow"
ScrollViewer.CanContentScroll="True"
CanUserAddRows="false"
ScrollViewer.VerticalScrollBarVisibility="Auto"
ScrollViewer.HorizontalScrollBarVisibility="Auto"
FontFamily="Arial"
CellEditEnding="dataGridParametros_CellEditEnding" >
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding IdParametro}" Header="Id" FontFamily="Arial" IsReadOnly="True" Visibility="Hidden"/>
<DataGridTextColumn Binding="{Binding Codigo}" Header="Código" FontFamily="Arial" IsReadOnly="True"/>
<DataGridTextColumn Width="200" Binding="{Binding Mnemonico}" Header="Mnemonico" FontFamily="Arial" IsReadOnly="True" />
<DataGridTextColumn Width="250*" Binding="{Binding Descricao}" Header="Descrição" FontFamily="Arial" IsReadOnly="True" />
<DataGridTemplateColumn Header="Valor" Width="150">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ContentControl Content="{Binding}">
<ContentControl.Style>
<Style TargetType="ContentControl">
<Style.Triggers>
<DataTrigger Binding="{Binding TipoCampo}" Value="CheckBox">
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<CheckBox IsChecked="{Binding Valor , Mode=TwoWay , UpdateSourceTrigger=PropertyChanged}"/>
</DataTemplate>
</Setter.Value>
</Setter>
</DataTrigger>
<DataTrigger Binding="{Binding TipoCampo}" Value="ComboBox">
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<ComboBox ItemsSource="{Binding Valor , Mode=TwoWay , UpdateSourceTrigger=PropertyChanged}" />
</DataTemplate>
</Setter.Value>
</Setter>
</DataTrigger>
<DataTrigger Binding="{Binding TipoCampo}" Value="TextBox">
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<TextBox Text="{Binding Valor , Mode=TwoWay , UpdateSourceTrigger=PropertyChanged}" />
</DataTemplate>
</Setter.Value>
</Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</ContentControl.Style>
</ContentControl>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>

Data grid display icon on one column

IM using data grid which are filled with data during RT(Im using mvvm).
I bind the data grid to observer collection which is updated during RT with values.
one of the fields are isKey .if this value is true I want to display some icon of key.
how can i do that?
I need to add the icon just when key is true .
this is my code
model
public bool IsKey { get; set; }
public string Column2 { get; set; }
public string Column3 { get; set; }
{
public ViewModel()
{
this.Items = new List<MyClass>();
//row 1:
this.Items.Add(new MyClass { IsKey= true,Column2 = "aaaa",Column3 = "ddfa",Column4 = "fddsfas",Column5 = "dfadsfas"});
//row 2:
this.Items.Add(new MyClass { IsKey = false ,Column2 = "aaaa",Column3 = "ddfa",Column4 = "fddsfas",Column5 = "dfadsfas"});
}
the xaml
</DataGridTemplateColumn>
<DataGridTextColumn Binding="{Binding isKey}" Header="2" Width="*" />
<DataGridTextColumn Binding="{Binding Column2}" Header="2" Width="*" />
<DataGridTextColumn Binding="{Binding Column3}" Header="3" Width="*" />
<DataGridTextColumn Binding="{Binding Column4}" Header="4" Width="*" />
You need DataGridTemplateColumn. Set its CellTemplate to contain ContentControl whose Content will be null in case IsKey value is false and set it to Icon when value is true for IsKey.
<DataGridTemplateColumn IsReadOnly="True">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ContentControl x:Name="content"/>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding IsKey}" Value="True">
<Setter TargetName="content" Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<Image Source="IconSourcePath" Height="30"/>
</DataTemplate>
</Setter.Value>
</Setter>
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>

Edit Datagrid row background based on object value

I have the following class:
public class Order
{
public int Id { get; set; }
public string OrdName { get; set; }
public int Quant { get; set; }
public int Supplied { get; set; }
}
and this DataGrid:
<DataGrid x:Name="dgOrders" Margin="5" CanUserAddRows="False" CanUserDeleteRows="False"
SelectionMode="Extended" ItemsSource="{Binding}"
SelectionUnit="FullRow" VerticalScrollBarVisibility="Auto"
Height="300" Width="700" HorizontalAlignment="Left" AutoGenerateColumns="False" Grid.Row="2">
<DataGrid.Columns>
<DataGridTextColumn Header="Order Name" Binding="{Binding OrdName}" IsReadOnly="True"/>
<DataGridTextColumn Header="Quantity" Binding="{Binding Quant}" IsReadOnly="True"/>
<DataGridTextColumn Header="Supplied" Binding="{Binding Supplied}" IsReadOnly="True"/>
</DataGrid.Columns>
</DataGrid>
What I want is that when the Quantity and Supplied properties are equal the row background color will change.
I tried it with an Event Trigger and a Converter but with no luck (possibly I didn't implement them in the xaml correctly).
also trying to do this from the code behind didn't work (tried to get the row instance like this suggests but I keep getting null for the row).
A Binding cannot be set on the Value property of a DataTrigger. Therefore, you'll need to add an extra property into your data type class:
public bool AreQuantityAndSuppliedEqual
{
return Quantity == Supplied;
}
Then, with this property, you can use the following Style:
<Style x:Key="EqualRowStyle" TargetType="{x:Type DataGridRow}">
<Style.Triggers>
<DataTrigger Binding="{Binding AreQuantityAndSuppliedEqual}" Value="True">
<Setter Property="Background" Value="LightGreen" />
</DataTrigger>
</Style.Triggers>
</Style>
It would be used like so:
<DataGrid ItemsSource="{Binding YourItems}"
RowStyle="{StaticResource EqualRowStyle}" ... />

Categories