UWP ListView x: Bind SelectionMode StackoOverflowException - PullRequest
0 голосов
/ 11 мая 2018

У меня есть ListView, и я хочу изменить SelectionMode в ViewModel.Это работает наполовину.Это работает, что я нажимаю кнопку, и SelectionMode меняется между Single и Multiple.Но если у меня есть выбранный элемент в ListView и я изменил его на Multiple, я получаю исключение StackOverflowException в этой точке в MainPage.g.cs:

public static void Set_Windows_UI_Xaml_Controls_ListViewBase_SelectionMode(global::Windows.UI.Xaml.Controls.ListViewBase obj, global::Windows.UI.Xaml.Controls.ListViewSelectionMode value)
        {
            obj.SelectionMode = value; //<--- here is the error
        }

Вот мой ListView:

<ListView x:Name="MyList" Grid.Row="2" ItemsSource="{x:Bind ViewModel.Threads, Mode=OneWay}" SelectedItem="{x:Bind ViewModel.Selected, Mode=TwoWay}" ShowsScrollingPlaceholders="True" SelectionMode="{x:Bind ViewModel.ListSelectionMode, Mode=OneWay}">
                <interactivity:Interaction.Behaviors>
                    <core:EventTriggerBehavior EventName="SelectionChanged">
                        <core:InvokeCommandAction Command="{x:Bind ViewModel.SelectionChangedCommand}"
                                  InputConverter="{StaticResource SelectionChangedConverter}"
                                  InputConverterParameter="{Binding ElementName=MyList}" />
                    </core:EventTriggerBehavior>
                </interactivity:Interaction.Behaviors>
</ListView>

Вот ViewModel:

private ListViewSelectionMode _listSelectionMode = ListViewSelectionMode.Single;
    public ListViewSelectionMode ListSelectionMode
    {
        get { return _listSelectionMode; }
        set
        {
            if (_listSelectionMode != value)
            {
                _listSelectionMode = value;
                RaisePropertyChanged();
            }
        }
    }

    private List<object> _selectedThreads = new List<object>();
    public List<object> SelectedThreads
    {
        get { return _selectedThreads; }
        set
        {
            if (value != _selectedThreads)
            {
                _selectedThreads = value;
                RaisePropertyChanged();
            }
        }
    }

    private string _selectedThreadCounter;
    public string SelectedThreadCounter
    {
        get { return _selectedThreadCounter; }
        set
        {
            if (value != _selectedThreadCounter)
            {
                _selectedThreadCounter = value;
                RaisePropertyChanged();
            }
        }
    }

private RelayCommand<IList<object>> _selectionChangedCommand;
    public RelayCommand<IList<object>> SelectionChangedCommand
    {
        get
        {
            if (_selectionChangedCommand == null && ListSelectionMode == ListViewSelectionMode.Multiple)
            {
                _selectionChangedCommand = new RelayCommand<IList<object>>(
                    items =>
                    {
                        SelectedThreads = items.ToList();
                        SelectedThreadCounter = "(" + SelectedThreads.Count + ")";
                    }
                );
            }

            return _selectionChangedCommand;
        }
    }

Вот SelectionChangedConverter:

public class SelectionChangedConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, string language)
    {
        var listView = parameter as ListView;

        return listView.SelectedItems;
    }

    public object ConvertBack(object value, Type targetType, object parameter, string language)
    {
        throw new NotImplementedException();
    }
}

Надеюсь, этого кода достаточно, чтобы помочь найти ответ.

ОБНОВЛЕНИЕ: Может быть, я должен добавить, что мой ItemsSource выглядит так во ViewModel:

private IRealmCollection<ThreadRealm> _threads;
    public IRealmCollection<ThreadRealm> Threads
    {
        get { return _threads; }
        set
        {
            if (_threads != value)
            {
                _threads = value;
                RaisePropertyChanged();
            }
        }
    }

это IRealmCollection из Realm database

1 Ответ

0 голосов
/ 15 мая 2018

Согласно вашему описанию и фрагменту кода, я сделал пример кода для тестирования. Это хорошо с моей стороны.

Пожалуйста, проверьте следующий код:

<Page.Resources>
    <local:SelectionChangedConverter x:Key="SelectionChangedConverter"></local:SelectionChangedConverter>
</Page.Resources>

<Grid>
    <ListView x:Name="MyList" Grid.Row="2" ItemsSource="{x:Bind ViewModel.Threads,Mode=OneWay}" SelectedItem="{x:Bind ViewModel.Selected,Mode=TwoWay}" ShowsScrollingPlaceholders="True" SelectionMode="{x:Bind ViewModel.ListSelectionMode,Mode=OneWay}">
        <interactivity:Interaction.Behaviors>
            <core:EventTriggerBehavior EventName="SelectionChanged">
                <core:InvokeCommandAction Command="{x:Bind ViewModel.SelectionChangedCommand}"
                              InputConverter="{StaticResource SelectionChangedConverter}"
                              InputConverterParameter="{Binding ElementName=MyList}" />
            </core:EventTriggerBehavior>
        </interactivity:Interaction.Behaviors>
    </ListView>

    <Button Content="switch" Click="Button_Click"></Button>
</Grid>
public sealed partial class MainPage : Page
{
    private ViewModel _viewModel;

    public ViewModel ViewModel { get => _viewModel; set => _viewModel = value; }
    public MainPage()
    {
        this.InitializeComponent();
        ViewModel = new ViewModel();
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        ViewModel.ListSelectionMode = MyList.SelectionMode==ListViewSelectionMode.Multiple?ListViewSelectionMode.Single:ListViewSelectionMode.Multiple;
    }
}
public class ViewModel:ViewModelBase
{
    private ListViewSelectionMode _listSelectionMode = ListViewSelectionMode.Single;
    public ListViewSelectionMode ListSelectionMode
    {
        get { return _listSelectionMode; }
        set
        {
            if (_listSelectionMode != value)
            {
                _listSelectionMode = value;
                RaisePropertyChanged();
            }
        }
    }

    private List<object> _selectedThreads = new List<object>();
    public List<object> SelectedThreads
    {
        get { return _selectedThreads; }
        set
        {
            if (value != _selectedThreads)
            {
                _selectedThreads = value;
                RaisePropertyChanged();
            }
        }
    }

    private string _selectedThreadCounter;
    public string SelectedThreadCounter
    {
        get { return _selectedThreadCounter; }
        set
        {
            if (value != _selectedThreadCounter)
            {
                _selectedThreadCounter = value;
                RaisePropertyChanged();
            }
        }
    }

    private RelayCommand<IList<object>> _selectionChangedCommand;
    public RelayCommand<IList<object>> SelectionChangedCommand
    {
        get
        {
            if (_selectionChangedCommand == null && ListSelectionMode == ListViewSelectionMode.Multiple)
            {
                _selectionChangedCommand = new RelayCommand<IList<object>>(
                    items =>
                    {
                        SelectedThreads = items.ToList();
                        SelectedThreadCounter = "(" + SelectedThreads?.Count + ")";
                    }
                );
            }

            return _selectionChangedCommand;
        }
    }


    private ObservableCollection<string> _Threads;
    public ObservableCollection<string> Threads
    {
        get { return _Threads; }
        set
        {
            _Threads = value;
            RaisePropertyChanged();
        }
    }

    private string _Selected;
    public string Selected
    {
        get { return _Selected; }
        set
        {
            if (this._Selected != value)
            {
                _Selected = value;
                RaisePropertyChanged();
            }
        }
    }

    public ViewModel()
    {
        Threads = new ObservableCollection<string>();
        Threads.Add("1");
        Threads.Add("2");
        Threads.Add("3");
    }
}
public class SelectionChangedConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, string language)
    {
        var listView = parameter as ListView;

        return listView.SelectedItems;
    }

    public object ConvertBack(object value, Type targetType, object parameter, string language)
    {
        throw new NotImplementedException();
    }
}
...