Reputation: 14667
I have a ListView of which ItemSource is set to my Custom Collection.
I have defined a GridView CellTemplate that contains a combo box as below :
<ListView
MaxWidth="850"
Grid.Row="1"
SelectedItem="{Binding Path = SelectedCondition}"
ItemsSource="{Binding Path = Conditions}"
FontWeight="Normal"
FontSize="11"
Name="listview">
<ListView.View>
<GridView>
<GridViewColumn
Width="175"
Header="Type">
<GridViewColumn.CellTemplate>
<DataTemplate>
<ComboBox
Style="{x:Null}"
x:Name="TypeCmbox"
Height="Auto"
Width="150"
SelectedValuePath="Key"
DisplayMemberPath="Value"
SelectedItem="{Binding Path = MyType}"
ItemsSource="{Binding Path = MyTypes}"
HorizontalAlignment="Center" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</ListView>
public MyType : INotifyPropertyChanged
{ string Key; string Value;
public string Key { get { return _key; }
set { _key = value; this.OnPropertyChanged("Key"); } }
public string Value { get { return _value; }
set { _value = value; this.OnPropertyChanged("Value"); } }
public MyType ()
{
}
public MyType (string key, string value)
{
_key = key;
_value = value;
}
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
void OnPropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = this.PropertyChanged;
if (handler != null)
handler(this, new PropertyChangedEventArgs(propertyName));
}
#endregion
}
public void MoveUpExecuted()
{
int oldIndex = this.Conditions.IndexOf(_selectedCondition);
//Check if the selected item is not the first item
if (oldIndex != 0)
{
int newIndex = oldIndex - 1;
this.Conditions.Move(oldIndex, newIndex);
}
}
My Custom collection is the ObservableCollection.
I have a two buttons - Move Up and Move Down on top of the listview control . When user clicks on the Move Up or Move Down button I call Move method of Observable Collection.
But when I Move Up and Move Down the rows then the Selected Index of a combo box is -1.
I have ensured that selectedItem is not equal to null when performing Move Up and Move Down commands.
Please Help!!
Upvotes: 1
Views: 435
Reputation: 1904
I don't get this part:
I call MoveUp and MoveDown methods of Observable Collection.
ObservableCollection does not have such methods, at least not to my knowledge? Neither has it a notion of a current item or similar.
My apologies if I have missed something that could possibly render this post as ignorant.
What you could do is instead of binding your ListView to an ObservableCollection, you could bind it to a ICollectionView (derived from your ObservableCollection). If you set IsSynchronizedWithCurrentItem=True on ListView, you won't need to bind SelectedItem, it will be automatically bound to CurrentItem on ICollectionView.
ICollectionView also implements MoveCurrentToNext and MoveCurrentCurrentToPrevious which can be bound from your buttons (via ICommand).
EDIT: Now that new information is on the table, my above answer is not really relevant anymore. But I don't (yet) know the SO convention how to handle this, if I should delete the post entirely, edit out the above or just add the "new" reply. For now I'll edit this post.
I tried to recreate your project and your problem. Hopefully I have understood your problem right, and recreated it similarly at least.
As in the problem being the combobox not holding its value when it is being moved in the listview, it works for me.
Below are the relevant code (some of it hidden to avoid too much noise).
Does this help you?
public class MainWindowViewModel:INotifyPropertyChanged
{
private Condition _selectedCondition;
public ObservableCollection<Condition> Conditions { get; set; }
public Condition SelectedCondition
{
get
{
return _selectedCondition;
}
set
{
if (_selectedCondition != value)
{
_selectedCondition = value;
OnPropertyChanged("SelectedCondition");
}
}
}
...
public void MoveUpExecuted()
{
int oldIndex = this.Conditions.IndexOf(_selectedCondition);
//Check if the selected item is not the first item
if (oldIndex != 0)
{
int newIndex = oldIndex - 1;
this.Conditions.Move(oldIndex, newIndex);
}
}
And the condition class:
public class Condition : INotifyPropertyChanged
{
private MyType myType;
public ObservableCollection<MyType> MyTypes { get; set; }
public MyType MyType
{
get { return myType; }
set
{
if (myType != value)
{
myType = value;
OnPropertyChanged("MyType");
}
}
}
public Condition()
{
MyTypes = new ObservableCollection<MyType>() { new MyType() { Key = "1", Value = "One" }, new MyType() { Key = "2", Value = "Two" } };
MyType = MyTypes[1];
}
... etc
<ListView
SelectedItem="{Binding Path=SelectedCondition}"
ItemsSource="{Binding Path=Conditions}"
FontWeight="Normal"
FontSize="11"
Name="listview" Margin="0,32,0,0">
<ListView.View>
<GridView>
<GridViewColumn
Width="175"
Header="Type">
<GridViewColumn.CellTemplate>
<DataTemplate>
<ComboBox
Width="150"
SelectedValuePath="Key"
DisplayMemberPath="Value"
SelectedItem="{Binding Path=MyType}"
ItemsSource="{Binding Path=MyTypes}"
HorizontalAlignment="Center" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
<Button Content="Move up"
Command="{Binding MoveUpCommand}"
/>
Upvotes: 1
Reputation: 2804
Swap these lines:
SelectedItem="{Binding Path = SelectedCondition}"
ItemsSource="{Binding Path = Conditions}"
ItemSource needs to be before the SelectedItem
Upvotes: 0