WPF Combobox in TableView can't show first item as default - c#

I'm using Combobox in TableView, and i want to show the first item text as its default value, i tried to add SelectionIndex=0, but it didn't work, its default value is empty. Different with other question like
Comboxbox auto select first item when data is available
my combobox belongs to TableView, each item has a combobox(actually each grid item has many types of combobox), so i can't use some methods need to handle it one by one.
my code is as below, and the itemsource Cities is a Dictionary, and i use DisplayMemberPath="Value" SelectedValuePath="Value" to show its value(not key):
<dxg:GridColumn FieldName="FloorSetUp" Header="Type" MinWidth="20" HorizontalHeaderContentAlignment="Center" VisibleIndex="1">
<dxg:GridColumn.CellTemplate>
<DataTemplate>
<ComboBox DisplayMemberPath="Value" SelectedValuePath="Value" ItemsSource="{Binding Data.Cities}" SelectedIndex="0"/>
</DataTemplate>
</dxg:GridColumn.CellTemplate>
</dxg:GridColumn>
Anyone can solve this problem?thanks very much!

Is FloorSetUp also KeyValuePair<T,R>?
becuse if not, thats your problem.
The ComboBox has to work with data of same types both in items source and in selected item property.

Related

How do I get a DataGridTemplateColumn to work with objects implementing the IEditable<T> interface?

I have a DataGrid with a DataGridComboBox column that works fine. It binds properly to the list of items, correctly displays the selected item, correctly selects an item, and binds the selected item's ID to the underlying row model properly.
It looks like this:
<DataGridComboBoxColumn
x:Name="AssetColumn"
Width="3*"
DisplayMemberPath="Item"
Header="Item"
ItemsSource="{Binding Data.AssetDescriptions, Source={StaticResource proxy}}"
SelectedValueBinding="{Binding AssetDescriptionID}"
SelectedValuePath="AssetDescriptionID" />
I'm trying to achieve the same thing with a DataGridTemplateColumn and an ordinary combo box. My effort:
<DataGridTemplateColumn Header="ItemTemplate" Width="3*">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ComboBox
DisplayMemberPath="Item"
ItemsSource="{Binding Data.AssetDescriptions, Source={StaticResource proxy}}"
SelectedValue="{Binding AssetDescriptionID, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
SelectedValuePath="AssetDescriptionID" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
Unfortunately, this one doesn't respect the IEditable<T> interface that the Asset objects implement. Consequently, the usual editing mechanisms that you would normally have in a DataGrid, such as undo, will not work for this column.
Is there a way to write this in such a way that it works the way it's supposed to with the IEditable<T> interface?
Note: I am aware that I probably need a CellEditingTemplate to get this to work properly, but I'm not sure how to go about that. I can put the same combo box in the CellEditingTemplate as well, but I can't figure out how to get the column to switch over to editing mode once it receives the focus, and if I only put the combo box data template in the CellEditingTemplate, no data is displayed in the column.

Combobox selected item binding inside Datagrid in WPF not working

I am having a issue with a Combo box inside a datagrid in WPF.
I want the arrow on the combo box to be visible even when it is not in editing mode. I couldn't achieve this behavior with DataGridComboBoxColumn which otherwise was working fine. To fix this appearance issue I had to use normal combo box.
<DataGridTemplateColumn Header="Parameter Group" MinWidth="150" Width="*">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ComboBox ItemsSource="{Binding Source={StaticResource GroupList}}"
DisplayMemberPath="ParameterGroupName"
IsSynchronizedWithCurrentItem="True"
SelectedValuePath="ParameterGroupName"
SelectedValue="{Binding Path=ParameterGroup,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
>
</ComboBox>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
Now the problem is that the selected item binding is not working. Any item selected for a row is applying for all. I am not sure what's wrong here.
The item source is-
private ObservableCollection<ParameterGroupModel> _parameterGroupList;
public ObservableCollection<ParameterGroupModel> ParameterGrpList
{
get
{
return _parameterGroupList;
}
set
{
_parameterGroupList = value;
NotifyPropertyChanged("ParameterGrpList");
}
}
And the selected value is a simple string inside the model.
Can someone please help?
With the CellTemplate you 'duplicate" the same xaml code in each cell at running time, thus the same bindings. So each cell refers to the same datasource and the same selectedItem object.
You must define somewhere a collection of object on which each row can bind separately its selected item and refer to it specifically in each cell
(one possible solution may be to use a multibinding with the selectedItemCollection and the row number for exemple to determine which item of the selectedItemCollection your row has to bind to)

combobox and listview binding issue wpf c#

I have a combobox which displays listview on dropdown, I am following MVVM Pattern and i have also set the public property in my Viewmodel and it works fine when i am assigning it to the Label but for Combobox it doesn't seem to rely on my binding. i tried numerous ways but unable to find the issue.
XAML :
<ComboBox Name="SearchBox" IsEditable="True" Background="White" md:HintAssist.Hint="Search MUID" Grid.Column="1" Margin="5 0 0 0"
Grid.Row="0" Height="40" Width="400" HorizontalContentAlignment="Left" HorizontalAlignment="Left" SelectedItem="{Binding ElementName=lstview ,Path=SelectedItem}" >
<ComboBoxItem>
<ListView x:Name="lstview" ItemsSource="{Binding filterSW}"
SelectedItem="{Binding SelectedMU}"
Height="200" ScrollViewer.VerticalScrollBarVisibility="Visible">
<ListView.View>
<GridView>
<GridViewColumn Width="130" Header="Mu-ID" />
<GridViewColumn Width="130" Header="MU-Identifier" DisplayMemberBinding="{Binding MU_Identifier}" />
<GridViewColumn Width="130" Header="Status" DisplayMemberBinding="{Binding RequestType}" />
<GridViewColumn Width="130" Header="UniqueID" />
</GridView>
</ListView.View>
</ListView>
</ComboBoxItem>
</ComboBox>
This works fine for me when i am using the public property and accessing its element , i also tried setting text={Binding SelectedMU.MU_Identifier} and selectedvalue but its just not working.
<Label Grid.Column="3" HorizontalAlignment="Center" Background="GreenYellow" Content="{Binding SelectedMU.MU_Identifier}"></Label>
It looks like you're trying to show a multi-column list in your ComboBox dropdown instead of the standard list where each item shows just a text line.
To achieve this effect you've placed a ListView inside the dropdown.
Unfortunately, this is just not going to work.
Both ComboBox and ListView descend from Selector which is an abstraction that allows to select an item from a list. This limits the property SelectedItem to one of the items that are contained in the list. If you try to assign to this property any value that it not in the list, the assignment is not going to work and the property will retain the value it had before you did the assignment.
Now, the list could either be specified right inside XAML or provided as a binding to property ItemsSource. You do the binding correctly for the ListView. But for the ComboBox you don't specify that binding. Instead you specify exactly one item of type ComboBoxItem which contains the whole ListBox as its value. So the only value that could be successfully assigned to the SelectedItem property of the ComboBox is that single ComboBoxItem. But your binding is never going to assign that value, that's why the ComboBox never shows anything when closed.
When it's open it does show the single item which contain the ListView but this is just an optical effect. The data binging is not going to work. The reason why it works for the Label is because the Label is not constrained and can show anything that the ListView tells it to show.
You can synchronize the ListView and the ComboBox only when both controls have the same bindings for both ItemsSource and SelectedItem properties. But in this case you won't be able to place the ListView inside the dropdown.
The closest you can get to what you want is by customizing the ComboBox's template as described in https://zamjad.wordpress.com/2012/08/15/multi-columns-combo-box, for example. What this won't give you compared to ListView is the column headers. Also, the columns will be evenly spaced inside the dropdown but this is what you have in your ListView anyway.
If you want to auto-size them, you'd need to add Width="Auto" SharedSizeGroup="cN" to each ColumnDefinition where "cN" should have the column number instead of N to make them unique within the Grid and add Grid.IsSharedSizeScope="True" to the <ComboBox >
That's a lot of trouble for something that one would expect to be much simpler, but, unfortunately, you cannot place a ListView inside the ComboBox's template, that's a limitation of how the base class Selector works with its items list.
There are other options if you are open to consider 3rd party control libraries. I worked with Syncfusion, they have SfMultiColumnDropDown which does what you want. I'm pretty sure other popular libraries have similar controls as well.

ComboBox selection in DataGrid gets reset when clicking on another column

I have a DataGrid with two Columns. One is a DataGridTextColumn the other is a DataGridComboBoxColumn. Both are bound to property and are editable. So when I change the selection of the ComboBox and then click at some white space the cell shows the correct selection. But if I click at the TextColumn beside it the ComboBox exits editing mode and resets the selection to whatever was selected before.
Why is this happening and what can I do to prevent this from happening?
Since you haven't posted your code I'm making assumptions as to what your problem is.
You need to specify TwoWay mode in your DataGrid.
You need to Bind the property SelectedValueBinding in your DataGridComboBoxColumn
<DataGridComboBoxColumn x:Name="DropDownComboBox" SelectedValueBinding="{Binding Path=FieldFromData}" Header="SomeName" IsReadOnly="False"/>
In the code define the combobox contents.
DropDownComboBox.ItemsSource = Enum.GetValues(typeof(ValuesPossible));
If you don't have the Binding set to the property in the data set you are displaying, it will just be a drop down that doesn't change the value of the data anywhere. The above example takes and populates the combobox with the values that could be selected and selects what is contained in the data set for the FieldFromData.
You will also need to bind the DataGrid in two way mode to allow the selected value to change the field.
<DataGrid ..<properties>.. ItemsSource="{Binding DataCollection,Mode=TwoWay}" />
<DataGridTemplateColumn Visibility="Visible" Header="Reason Id" Width="250">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<StackPanel>
<ComboBox x:Name="" SelectedValue="{Binding TypeId}" SelectedValuePath="TypeId" DisplayMemberPath="Type"
ItemsSource="{Binding TypeItems}" ></ComboBox>
</StackPanel>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
Check your columns DataPropertyName property.
I had a similar issue. The 'Type' was never getting set. Code was getting set twice, but incorrectly on the 2nd time.
Incorrect:
grcLocMill2Code.DataPropertyName = "MillCodeId";
grcLocMill2Code.DataPropertyName = "MillTypeId";
Correct:
grcLocMill2Code.DataPropertyName = "MillCodeId";
grcLocMill2Type.DataPropertyName = "MillTypeId";

Select ListView item when combobox/textbox is selected WPF MVVM

I have a ListView which contains a collection of objects as itemssource and the selected object as SelectedItem.
<ListView Margin="5 0 5 0" ItemsSource="{Binding ObjectCollection}" SelectedItem="{
Binding SelectedObject}" Grid.Row="1">
Inside the ListView.View I have several GridViewColumns which each have a CellTemplate
<GridViewColumn CellTemplate="{StaticResource ReferenceToCellTemplate}" Header="{
Binding ColumnName, Converter={StaticResource upperConverter}}" Width="90"
HeaderContainerStyle="{StaticResource StaticGridViewColumnHeaderStyleWhite}"/>
An example of such a template:
<DataTemplate x:Key="ReferenceToCellTemplate">
<ComboBox ItemsSource="{Binding PossibleValuesForProperty, UpdateSourceTrigger=
PropertyChanged}" SelectedItem="{Binding SelectedProperty, UpdateSourceTrigger=
PropertyChanged}" SelectionChanged="Protocol_ComboBox_SelectionChanged"/>
</DataTemplate>
Now for the issue:
Say that I have 2 comboboxes in this listview. for example a combobox with different software and another with the different versions of this software.
Whenever the software has changed in a certain row, the possible versions should be updated.
The question:
How do I know which object the software combobox belongs too so that I can adjust the possible versions for this object?
When you change the value inside the combobox, this doesn't mean that the row is selected. So when I try to adjust the versions along with the selected row, I might as well be adjust the wrong row.
So the way I see it there are 2 possibilities:
Select the given row whenever something inside that row is adjusted/selected
Get to know which row the changed/selected control is in without selecting it
Any help would be much appreciated.
The solution is to not use an event handler for when the property is changed but just to handle the change in the properties for the row object. So when the property for "software" changes, call a method which adjust the "PossibleVersions" property for this software. All of this inside the VM for the row object.
Basic beginner MVVM mistake I guess

Categories

Resources