wpf datagrid automatically expand first group - wpf

I have a datagrid with the itemsource bound to a ListCollectionView with one group.
When i fill the collection, i want the first group autmatically viewed as expanded, how to code that in wpf (codebehind or mvvm)?
<DataGrid
ItemsSource="{Binding ResultColl}"
SelectedItem="{Binding Path=SelectedResultItem, Mode=TwoWay}"
SelectionMode="Single" IsReadOnly="True" >
<DataGrid.GroupStyle>
<GroupStyle>
<GroupStyle.ContainerStyle>
<Style TargetType="{x:Type GroupItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type GroupItem}">
<Expander>
<Expander.Header>
<StackPanel>
<TextBox Text="{Binding Items[0].ID}" />
</StackPanel>
</Expander.Header>
<ItemsPresenter />
</Expander>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</GroupStyle.ContainerStyle>
</GroupStyle>
</DataGrid.GroupStyle>
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding Path=ID}"/>
<DataGridTextColumn Binding="{Binding Path=Typ}"/>
<DataGridTextColumn Binding="{Binding Path=Info}"/>
<DataGridTextColumn Binding="{Binding Path=orderDate, StringFormat={}{0:dd-MM-yyyy}}"/>
</DataGrid.Columns>
</DataGrid>
In the mvvm controller:
ListCollectionView tmp = new ListCollectionView(myList);
tmp.GroupDescriptions.Add(new PropertyGroupDescription("ID"));
ResultColl = tmp;
...
ListCollectionView _resultColl;
public ListCollectionView ResultColl
{
get { return _resultColl; }
set { _resultColl = value;
RaisePropertyChanged("ResultColl");
if (value != null && _resultColl.Count > 0)
SelectedResultItem = _resultColl.GetItemAt(0) as ItemResult;
}
}
When executing the code, the datagrid is filled the 1st item is selected but group is collapsed.

Add IsExpanded property to your class and add binding to Expander:
<Expander IsExpanded="{Binding Items[0].IsExpanded}">
Set IsExpanded for first to true

you can try add another bool property to your View Model defaulted to true but switching to false when first time used. And bind IsExpanded property of Expander to this with OneTime mode.
public bool IsExpanded
{
get
{
if (_isExpanded)
{
_isExpanded = false;
return true;
}
return false;
}
}
Xaml would be like that:
<Expander IsExpanded="{Binding DataContext.IsExpanded, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGrid}}, Mode=OneTime}">

Related

WPF Hide an Item of a Combobox ItemSource

In my WPF View, I have a DataGrid which Display Data from a Database.
One column is a combobox that is bound to a string in Database.
This is the list of available string :
public List<string> AvailableTypeImpression { get; } = new List<string>() {"S","D","T","X","M","p","P","R"}
All these string could be displayed in the datagrid, but if the user want to edit it, I can only set S, D, T, or X. The user is not allowed to set M, p, P or R.
So I would like to hide these four letter from the combobox available Items. But I don't really know how to do that in a simple way (I found some solution on Stack Overflow but it doesn't work in my case).
Here's the code of my datagrid :
<DataGrid Grid.Row="1" x:Name="LotsListDataGrid" IsReadOnly="False" SelectionMode="Single" SelectionUnit="FullRow" SelectedItem="{Binding SelectedLot}" ItemsSource="{Binding FilteredList}" VirtualizingPanel.IsVirtualizing="True" EnableRowVirtualization="True" HorizontalScrollBarVisibility="Auto">
<DataGrid.Columns>
<DataGridTextColumn Header="Lot" Width="200" Binding="{Binding Value.Lot.Intitule}" IsReadOnly="True"/>
<DataGridTemplateColumn Header=".i." HeaderStyle="{StaticResource CenteredColumnHeaderStyle}" Width="545" IsReadOnly="False">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ComboBox Height="23" Style="{StaticResource AnfComboBoxStyle}" ItemsSource="{Binding DataContext.AvailableTypeImpression, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGrid}}}" SelectedItem="{Binding Value.Lot.TypeImpression, UpdateSourceTrigger=PropertyChanged}">
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
FilteredList.Value.Lot.TypeImpression is a string.
If I've well understood, all the possible string must be in the ItemSource otherwise they could'nt be displayed. But I need to find a way to prevent user to select some of them.
Thanks for your help.
I don't know of a way to make individual items non-selectable in a combo box.
But you could always show a combo box without your not-allowed letters (i.e. remove them from AvailableTypeImpression), and instead show just a simple TextBlock in your cell in case one of these letters is read from the DB.
Change your cell template to something like this:
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Grid>
<ComboBox Visbility="{Binding IsValueEditable}" Height="23" Style="{StaticResource AnfComboBoxStyle}" ItemsSource="{Binding DataContext.AvailableTypeImpression, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGrid}}}" SelectedItem="{Binding Value.Lot.TypeImpression, UpdateSourceTrigger=PropertyChanged}" />
<TextBlock Visbility="{Binding NotIsValueEditable}" Height="23" Text="{Binding Value.Lot.TypeImpression}" />
</Grid>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
Then implement IsValueEditable, NotIsValueEditable properties in your ViewModel such that only one of the controls is shown.
Alternatively, if you also want to be able to modify existing entries of M, p, P, R, you could use a DataGridTemplateColumn.CellEditingTemplate:
Make the CellEditingTemplate show the ComboBox (without M, p, P, R options) while the regular CellTemplate only contains a TextBlock.
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Height="23" Text="{Binding Value.Lot.TypeImpression}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
<DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<ComboBox Height="23" Style="{StaticResource AnfComboBoxStyle}" ItemsSource="{Binding DataContext.AvailableTypeImpression, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGrid}}}" SelectedItem="{Binding Value.Lot.TypeImpression, UpdateSourceTrigger=PropertyChanged}" />
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
The solution from #dheller was good but not working in my case because the user is not able to give to "Value.Lot.TypeImpression" a new Value M ,p, P or R, but he's able to edit "Value.Lot.TypeImpression" even if it equals to M ,p, P or R and set S, D, T, or X.
So I've found another way :
In my ViewModel I've defined a new class :
public class TypeImpressionAvailable
{
public string Name { get; set; }
public bool IsAvailable { get; set; }
}
And my list to give to my combobox as ItemSource :
public List<TypeImpressionAvailable> AvailableTypeImpression { get; } = new List<TypeImpressionAvailable>() {
new TypeImpressionAvailable(){ Name="N", IsAvailable=true },
new TypeImpressionAvailable(){ Name="S", IsAvailable=true },
new TypeImpressionAvailable(){ Name="D", IsAvailable=true },
new TypeImpressionAvailable(){ Name="T", IsAvailable=true },
new TypeImpressionAvailable(){ Name="X", IsAvailable=true },
new TypeImpressionAvailable(){ Name="M", IsAvailable=false },
new TypeImpressionAvailable(){ Name="p", IsAvailable=false },
new TypeImpressionAvailable(){ Name="P", IsAvailable=false },
new TypeImpressionAvailable(){ Name="R", IsAvailable=false }
};
And in my View :
<DataGridTemplateColumn Header=".i." HeaderStyle="{StaticResource CenteredColumnHeaderStyle}" Width="45" IsReadOnly="False">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ComboBox Height="23" SelectedValuePath="Name" DisplayMemberPath="Name"
SelectedValue="{Binding Value.Lot.TypeImpression, UpdateSourceTrigger=PropertyChanged}"
>
<ComboBox.Style>
<Style TargetType="{x:Type ComboBox}" BasedOn="{StaticResource AnfComboBoxStyle}">
<Setter Property="ItemsSource" Value="{Binding DataContext.AvailableTypeImpression, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGrid}}}"/>
<Setter Property="ItemContainerStyle">
<Setter.Value>
<Style TargetType="ComboBoxItem" BasedOn="{StaticResource {x:Type ComboBoxItem}}">
<Style.Triggers>
<DataTrigger Binding="{Binding IsAvailable}" Value="False">
<Setter Property="Visibility" Value="Collapsed" />
</DataTrigger>
</Style.Triggers>
</Style>
</Setter.Value>
</Setter>
</Style>
</ComboBox.Style>
</ComboBox>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
And it works fine :)

DataGrid DataGridTemplateColumn ComboBox

I'm having trouble with my ComboBoxes in a DataGrid, let me explain with a few pictures.
This is the starting point.
Now if I want to add a new row I click the last row and hit Enter.
A new row is added and iv selected type table here and given it a name MY_TABLE, then I hit enter to add another row.
The result is this, the combobox for the previous added row's type selection has gone back to None. NOTE: that the checkboxes were previously grayed out as type None cant have any privileges, but table can have CRUD so when I selected type table they became enabled.
Here is the ViewModel (VM) for each row:
public class RoleHasPrivilegeOnObjectEntityViewModel : EntityViewModelBase<RoleHasPrivilegeOnObjectEntityViewModel, RoleHasPrivilegesOnObject>, IRoleHasPrivilegeOnObjectListItemViewModel
{
private readonly RoleHasPrivilegesOnObject _roleHasPrivilegesOnObject;
private ObservableCollection<ObjectTypeEntityViewModel> _availableObjectTypes;
private readonly ObjectTypeEntityViewModel _objectTypeEntityViewModel;
private IRoleEntityViewModel _role;
private IObjectEntityViewModel _object;
public RoleHasPrivilegeOnObjectEntityViewModel(RoleHasPrivilegesOnObject roleHasPrivilegesOnObject, IEnumerable<OBJECT_TYPE> availableObjectTypes)
{
_roleHasPrivilegesOnObject = roleHasPrivilegesOnObject;
AvailableObjectTypes = new ObservableCollection<ObjectTypeEntityViewModel>(availableObjectTypes.Select(ot => new ObjectTypeEntityViewModel(ot)));
_role = new RoleEntityViewModel(_roleHasPrivilegesOnObject.Role);
_object = new ObjectEntityViewModel(_roleHasPrivilegesOnObject.Object);
_objectTypeEntityViewModel = new ObjectTypeEntityViewModel(_roleHasPrivilegesOnObject.Object.OBJECT_TYPE);
}
public RoleHasPrivilegeOnObjectEntityViewModel(XROLE role, CONTAINER schema, OBJECT_TYPE currentObjectType, IEnumerable<OBJECT_TYPE> availableObjectTypes)
{
var objectTypes = availableObjectTypes as IList<OBJECT_TYPE> ?? availableObjectTypes.ToList();
_roleHasPrivilegesOnObject = new RoleHasPrivilegesOnObject(role,
new XOBJECT { CONTAINER = schema, OBJECT_TYPE = currentObjectType },
new List<OBJECT_HAS_PRIVILEGE>(),
objectTypes.SelectMany(aot => aot.PRIVILEGE));
AvailableObjectTypes = new ObservableCollection<ObjectTypeEntityViewModel>(objectTypes.Select(ot => new ObjectTypeEntityViewModel(ot)));
_role = new RoleEntityViewModel(_roleHasPrivilegesOnObject.Role);
_object = new ObjectEntityViewModel(_roleHasPrivilegesOnObject.Object);
_objectTypeEntityViewModel = new ObjectTypeEntityViewModel(_roleHasPrivilegesOnObject.Object.OBJECT_TYPE);
}
public override EntityType EntityType
{
get { return SelectedObjectType.EntityType; }
}
public ObjectTypeEntityViewModel SelectedObjectType
{
get { return _objectTypeEntityViewModel; }
set
{
_roleHasPrivilegesOnObject.Object.OBJECT_TYPE = value.OriginalEntity;
OnPropertyChanged();
OnPropertyChanged("CanHaveSelect");
...
}
}
public ObservableCollection<ObjectTypeEntityViewModel> AvailableObjectTypes
{
get { return _availableObjectTypes; }
set
{
_availableObjectTypes = value;
OnPropertyChanged();
}
}
public string ToolTip
{
get { return _roleHasPrivilegesOnObject.ToolTip; }
}
public bool HasSelect
{
get { return _roleHasPrivilegesOnObject.HasSelect; }
set
{
_roleHasPrivilegesOnObject.HasSelect = value;
OnPropertyChanged();
}
}
public bool CanHaveSelect
{
get
{
var canHaveSelect = _roleHasPrivilegesOnObject.CanHaveSelect;
if(!canHaveSelect && HasSelect) HasSelect = false;
return canHaveSelect;
}
}
...
public override string NAME
{
get { return _roleHasPrivilegesOnObject.NAME; }
set
{
_roleHasPrivilegesOnObject.NAME = value;
OnPropertyChanged();
OnPropertyChanged("Text");
}
}
}
And here is my View for the DataGrid
<UserControl ...
d:DataContext="{d:DesignInstance impl:PrivilegeDetailsViewModel}">
<UserControl.Resources>
<Style x:Key="DataGridContentCellCentering" TargetType="{x:Type DataGridCell}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGridCell}">
<Grid Background="{TemplateBinding Background}">
<ContentPresenter VerticalAlignment="Center" HorizontalAlignment="Center"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="CanHaveSelectStyle" TargetType="CheckBox">
<Style.Triggers>
<DataTrigger Binding="{Binding CanHaveSelect, UpdateSourceTrigger=PropertyChanged}" Value="True">
<Setter Property="IsEnabled" Value="True"/>
</DataTrigger>
<DataTrigger Binding="{Binding CanHaveSelect, UpdateSourceTrigger=PropertyChanged}" Value="False">
<Setter Property="IsEnabled" Value="False"/>
</DataTrigger>
</Style.Triggers>
</Style>
...
</UserControl.Resources>
<DataGrid x:Name="PrivilegeDataGrid"
ItemsSource="{Binding RolesHasPrivilegesOnObjects}"
AutoGenerateColumns="False"
CanUserReorderColumns="False"
CanUserResizeColumns="True"
CanUserResizeRows="False"
CanUserSortColumns="True"
CanUserAddRows="True"
IsTextSearchEnabled="True"
BorderThickness="0">
<DataGrid.Columns>
<DataGridTemplateColumn Header="Type" CanUserSort="True" MinWidth="120">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate DataType="{x:Type impl2:RoleHasPrivilegeOnObjectEntityViewModel}">
<ComboBox ItemsSource="{Binding AvailableObjectTypes}"
SelectedItem="{Binding SelectedObjectType}"
SelectedValue="{Binding SelectedObjectType.ID}"
SelectedValuePath="ID">
<ComboBox.ItemTemplate>
<DataTemplate DataType="{x:Type impl2:ObjectTypeEntityViewModel}">
<StackPanel Orientation="Horizontal">
<Image Source="{Binding Icon}" ToolTip="{Binding ToolTip}" Margin="0,0,3,0" Width="17" Height="17"/>
<TextBlock Text="{Binding ToolTip}"/>
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTextColumn Width="*" Header="Name" Binding="{Binding NAME}">
<DataGridTextColumn.EditingElementStyle>
<Style TargetType="TextBox">
<Setter Property="extensions:TextBoxUpperCaseBehavior.IsEnabled" Value="True"/>
</Style>
</DataGridTextColumn.EditingElementStyle>
</DataGridTextColumn>
<DataGridCheckBoxColumn Header="Select"
Binding="{Binding HasSelect, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"
CellStyle="{StaticResource DataGridContentCellCentering}"
ElementStyle="{StaticResource CanHaveSelectStyle}"
EditingElementStyle="{StaticResource CanHaveSelectStyle}" />
...
</DataGrid.Columns>
</DataGrid>
</UserControl>
I have tried all these variants for the ComboBox ItemsSource and SelectedItem
<ComboBox ItemsSource="{Binding AvailableObjectTypes}"
SelectedItem="{Binding SelectedObjectType}"
SelectedValue="{Binding SelectedObjectType.ID}"
SelectedValuePath="ID">
<ComboBox ItemsSource="{Binding AvailableObjectTypes}"
SelectedValue="{Binding SelectedObjectType.ID}"
SelectedValuePath="ID">
<ComboBox ItemsSource="{Binding AvailableObjectTypes}"
SelectedItem="{Binding SelectedObjectType}"
SelectedValuePath="ID">
<ComboBox ItemsSource="{Binding AvailableObjectTypes}"
SelectedItem="{Binding SelectedObjectType}">
What do I have to do to make the ComboBox behave as expected?
It seems that a simple UpdateSourceTrigger attribute was missing on the SelectedObjectType binding in the xaml for the ComboBox, like this
<ComboBox ItemsSource="{Binding AvailableObjectTypes}"
SelectedItem="{Binding SelectedObjectType, UpdateSourceTrigger=PropertyChanged}"
SelectedValue="{Binding SelectedObjectType.ID}"
SelectedValuePath="ID">

WPF listbox groupping by substrings

My object has property that stores more strings separated by separator.
I want to display list of such objects in WPF listbox with grouping enabled. What I need is to have groups according to substrings.
Object1: Property = "string1;string2;string3"
Object2: Property = "string2;string3"
I expect listbox to be displayed like that:
string1
Object 1
Object 2
string2
Object 1
string3
Object 1
Object 2
Is that possible?
Thank you for your help.
Create a wrapper class.
class MyGroup
{
public string GroupID;
public object SomeObject;
}
Build your flat list of that wrapper class.
private List<MyGroup> BuildItemsSourceTogether()
{
List<MyGroup>itemsSource = new List<MyGroup>();
foreach(var obj in myListWithObjectsWhichPropertiesAreStringsWhichFuthermoreContainSubstrings)
{
var stringArray = obj.Property123.Split(';');
foreach(var str in stringArray)
{
itemsSource.Add(new MyGroup () { GroupID = str, SomeObject = obj});
}
}
return itemsSource;
}
Tell what property in your wrapper class should be used for grouping.
class Window1
{
public Window1()
{
InitalizeComponents();
var finalData = new ListCollectionView(BuildItemsSourceTogether());
finalData.GroupDescriptions.Add(new PropertyGroupDescription("GroupID"));
this.DataContext = finalData;
}
}
In XAML set the look of your groups and let WPF group that flat list of IDs for you.
I used a DataGrid with columns. You can use a ListBox.
<DataGrid ItemsSource="{Binding}">
<DataGrid.GroupStyle>
<GroupStyle>
<GroupStyle.HeaderTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding Path=Name}" />
</StackPanel>
</DataTemplate>
</GroupStyle.HeaderTemplate>
<GroupStyle.ContainerStyle>
<Style TargetType="{x:Type GroupItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type GroupItem}">
<Expander>
<Expander.Header>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Path=Name}" />
<TextBlock Text="{Binding Path=ItemCount}"/>
<TextBlock Text="Items"/>
</StackPanel>
</Expander.Header>
<ItemsPresenter />
</Expander>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</GroupStyle.ContainerStyle>
</GroupStyle>
</DataGrid.GroupStyle>
<DataGrid.Columns>
<DataGridTextColumn Header="header1" Binding="{Binding SomeObject.Property321}" />
<DataGridTextColumn Header="header2" Binding="{Binding SomeObject.Property678}" />
</DataGrid.Columns>
</DataGrid>
Have fun.

How to bind ObservableCollection in DataGridComboBoxColumn in DataGrid?

I have already given ListCollectionView as "ListCollectionView1" to Grid and inGrid I have used DataGrid. "ListCollectionView1" contains both observable collection. "ObservableCollection1" DataGrid in and another observable collection as "ObservableCollection2" which is in "ObservableCollection1" observable collection as Itemsource to DataGridComboBoxColumn .
And as SelectedValueBinding I'm using Property as "a" from "ObservableCollection1"
but I'm not getting the values in DataGridComboBoxColumn
<Grid DockPanel.Dock="Bottom" DataContext="{Binding ListCollectionView1>
<DataGrid
ColumnWidth="130"
CanUserAddRows="True"
AutoGenerateColumns="False"
ItemContainerStyle="{StaticResource DataGridRowContentStyle}"
ItemsSource="{Binding ObservableCollection1 }"
CanUserDeleteRows="False">
<DataGridComboBoxColumn Header="Labour" ItemsSource="{Binding Path=ObservableCollection2 , RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}" SelectedValueBinding="{Binding Id}" SelectedValuePath="Id" DisplayMemberPath="Id" HeaderStyle="{StaticResource DataGridHeaderStyle}"/>
</DataGrid>
</Grid>
in my viewModel observable collections and listcollectionview are
private ListCollectionView _ListCollectionView1;
public ListCollectionView ListCollectionView1
{
get { return _ListCollectionView1; }
set
{
this._ListCollectionView1= value;
OnPropertyChanged("ListCollectionView1");
}
}
public ObservableCollection<Model_ObservableCollection1> ModelObservableCollection1
{
get { return new ObservableCollection<Model_ObservableCollection1>(ViewModel.AllDataCollactions.AllTransactionsDetails.Where(s => s.TransactionsID.Equals(TransactionsID))); }
}
public ObservableCollection<Model_ObservableCollection2> Model_ObservableCollection1
{
get { return new ObservableCollection<Model_ObservableCollection1>(ViewModel.AllDataCollactions.AllTransactionsDetails.Where(s => s.TransactionsID.Equals(TransactionsID) && s.IsJama)); }
}
Try this.
<DataGrid x:Name="testGrid" AutoGenerateColumns="True" ItemsSource="{Binding ObservableCollection}" >
<DataGrid.Columns>
<DataGridComboBoxColumn Header="Labour" DisplayMemberPath="test">
<DataGridComboBoxColumn.ElementStyle>
<Style TargetType="{x:Type ComboBox}">
<Setter Property="ItemsSource" Value="{Binding Path=DataContext.ObservableCollection2 , RelativeSource={RelativeSource AncestorType={x:Type Window}}}" />
</Style>
</DataGridComboBoxColumn.ElementStyle>
<DataGridComboBoxColumn.EditingElementStyle>
<Style TargetType="{x:Type ComboBox}">
<Setter Property="ItemsSource" Value="{Binding Path=DataContext.ObservableCollection2, RelativeSource={RelativeSource AncestorType={x:Type Window}}}" />
</Style>
</DataGridComboBoxColumn.EditingElementStyle>
</DataGridComboBoxColumn>
</DataGrid.Columns>
</DataGrid>
Add the DataContext in your style binding instead of just the property name. You are just setting the ItemsSource of the ColumnBoxHeader which doesn't make sense. It doesn't know how to populate the ComboBox where it is in the children of the control.

DataGridComboBoxColumn binding issue

I have DataGridComboBoxColumn in DataGrid:
<DataGridComboBoxColumn Header="{x:Static Properties:Resources.Unit}" Width="Auto"
SelectedValueBinding="{Binding UnitUnitId}"
SelectedValuePath="UnitId"
DisplayMemberPath="Name" >
<DataGridComboBoxColumn.ElementStyle>
<Style TargetType="ComboBox">
<Setter Property="ItemsSource" Value="{Binding Path=DataContext.Units,RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}"/>
</Style>
</DataGridComboBoxColumn.ElementStyle>
<DataGridComboBoxColumn.EditingElementStyle>
<Style TargetType="ComboBox">
<Setter Property="ItemsSource" Value="{Binding Path=DataContext.Units,RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}"/>
</Style>
</DataGridComboBoxColumn.EditingElementStyle>
</DataGridComboBoxColumn>
and ComboBox:
<ComboBox x:Name="unitBox" ItemsSource="{Binding Path=Units}"
SelectedItem="{Binding TaxSubGroup.Unit}"
Grid.Row="2"
Grid.Column="1" Margin="11,11,0,0" HorizontalAlignment="Stretch">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Converter={x:Static c:UnitToStringConverter.Default}}"/>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
Units property:
public ObservableCollection<Unit> Units
{
get
{
return _units;
}
set
{
if(_units!=value)
{
_units = value;
RaisePropertyChanged("Units");
}
}
}
when i'm changing ComboBoxes value, DataGridComboBoxColumn's value updating automatically, but changing DataGrid's comboboxcolumn's value not updating ComboBoxes value. Why?
UPDATED
The problem was in DataGridComboBoxCulumn's SelectedValueBinding property. All i needed is to add UpdateSourceTrigger property:
SelectedValueBinding="{Binding UnitUnitId,UpdateSourceTrigger=PropertyChanged}"
Are you updating TaxSubGroup.Unit in the setter of UnitUnitId property?
In your DataContext model class do something similar to this...
public int UnitUnitId
{
get
{
return this.unitID;
}
set
{
this.unitID = value;
this.TaxSubGroup.Unit = Units.FirstOrDefault(u => u.UnitID == value);
this.NotifyPropertyChange("UnitUnitId");
}
}
This will match SelectedItem of Combobox by reference.

Resources