views:

93

answers:

3

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!!

A: 

Swap these lines:

SelectedItem="{Binding Path = SelectedCondition}" 
ItemsSource="{Binding Path = Conditions}" 

ItemSource needs to be before the SelectedItem

Daniel
Thanks for the reply Daniel, It dosen't help either..
Ashish Ashu
Have you tried manipulating the SelectedIndex on the listview rather than the Move methods on the observableCollection I've never actually used them myself.
Daniel
I tried setting the selected Index = 0 ( hardcoded ) , but that also doesn't help me out...
Ashish Ashu
A: 

Did you try ItemsSource="{Binding Conditions}"

Veer
I have tried just now, but it dosen't solve the problem. I am still not able to retain the selected index of a combo box of a listview.
Ashish Ashu
some code will help. Also QuickWatch the MyType property while performing MoveUp operation.
Veer
From your code it is evident that MyType is the model and MyTypes is the list. But don't know why you bind the selected item to MyType. Shouldn't that be SelectedMyType, a property that has to be created?
Veer
Is this is the bug ?http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/af13c8b3-7e0e-43c0-87a7-53f5a5158512
Ashish Ashu
+1  A: 

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}"
                 />
Tendlon
Thanks for the reply. Sorry for the incorrect names of ObservableCollection, its Move method in ObservableCollection which move the entity in a collection from oldindex to new index
Ashish Ashu
Ah I see. So, just to be clear, you want to move the object it self, as in change order of items, not move the selection as I thought?
Tendlon
Yes, I set the selectedItem of ListView to the current object which is moved, that gives the selection in the listview
Ashish Ashu
Is this is the bug:http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/af13c8b3-7e0e-43c0-87a7-53f5a5158512
Ashish Ashu
I doubt it, that seems to be more about if style are set or not. Can you share the code for how you move the selected item?
Tendlon
Hi Tendlon , I have shared the code for moving the selected item. I am doing this in my Viewmodel.
Ashish Ashu
Many Many thanks Tendlon, I will try this code. Can you please send me the sample on mail ID ( [email protected] )
Ashish Ashu