Why does FlipView ignore SelectedItem

2019-06-22 07:30发布

问题:

I'd like to use a FlipView to display some items and start showing a specific item.

For this, I have defined a view model class:

class MyDataContext
{

    public MyDataContext()
    {
        Items = new List<MyClass>();
        Items.Add(new MyClass("1"));
        Items.Add(new MyClass("2"));
        Items.Add(new MyClass("3"));
        SelectedItem = Items[1];
    }

    public List<MyClass> Items { get; set; }
    public MyClass SelectedItem { get; set; }
}

As you can see, the selected item is not the first item.

Now for the XAML:

    <FlipView ItemsSource="{Binding Items}" SelectedItem="{Binding SelectedItem}"></FlipView>

However, when I run the app, the flip view shows the first item, not the second item.

Is this intentional?, or is it a bug?

回答1:

Try this

<FlipView
    ItemsSource="{Binding Items}"
    SelectedItem="{Binding SelectedItem, Mode=TwoWay}" />
  • your SelectedItem needs to be a TwoWay binding for it to work, since the value is set by both the control and the view model.


回答2:

Was having the same issue with the FlipView and unable to get the BindableBase or the TwoWay option to work. Because the order of the list was not really a topic for me, I've created a method to reorder the ItemsSource, to start with the SelectedItem as being the first item in the Collection.

In the underlying code, the result is the new ItemsSource for the FlipView, instead of the previous List elements.

    public static List<T> ReorderList(List<T> elements, T selectedElement)
    {
        var elementIndex = elements.FindIndex(x => x.Id == selectedElement.Id);
        var result = new List<T>();

        foreach (var item in elements)
        {
            if (elementIndex .Equals(elements.Count))
            {
                elementIndex = 0;
            }

            result.Add(elements[elementIndex]);

            elementIndex++;
        }

        return result;
    }


回答3:

On top of what Filip stated, you're class (MyDataContext) needs to notify the UI that the property has changed. Your ViewModel must implement INotifyPropertyChanged and the property needs to fire the PropertyChanged event

public class ViewModel : INotifyPropertyChanged
{
    private object _selectedItem;

    public object SelectedItem
    {
        get { return _selectedItem; }
        set 
        { 
            _selectedItem = value; 
            OnPropertyChanged("SelectedItem"); 
        }
    }
}

You can also use the BindableBase class that comes with the sample apps

public class ViewModel : BindableBase
{
    private object _selectedItem;

    public object SelectedItem
    {
        get { return this._selectedItem; }
        set { this.SetProperty(ref this._selectedItem, value); }
    }
}


回答4:

It's look like a bug. If you debug your code you will notice that at first your SelectedItem in VM set to the right element, then it sets to null and after that it sets to the first element of FlipView's ItemsSource collection.

As a workaround I see setting SelectedItem of VM after Loaded event of FlipView is raised.