x:尝试x时绑定StackOverflow:使用TwoWay模式绑定ListView.SelectedItem

RTD*_*Dev 5 c# win-universal-app windows-10 xbind

我正在尝试使用新的x:Bind绑定ListView.SelectedItem.我的代码:

视图:

//MainPage.xaml:

<Page
x:Class="BrokenListSample.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:BrokenListSample"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">

<Grid Background="Beige">
    <Grid.RowDefinitions>
        <RowDefinition></RowDefinition>
        <RowDefinition></RowDefinition>
    </Grid.RowDefinitions>

    <ListView Grid.Row="0" Background="LawnGreen" 
              ItemsSource="{x:Bind ViewModel.MyItems, Mode=OneWay}"
              SelectedItem="{x:Bind ViewModel.BestItem, Mode=TwoWay}"
              Width="300" Height="300"/>

    <ListView Grid.Row="1" Background="LawnGreen" 
              ItemsSource="{Binding MyItems, Mode=OneWay}"
              SelectedItem="{Binding BestItem, Mode=TwoWay}"
              Width="300" Height="300"/>
</Grid>
Run Code Online (Sandbox Code Playgroud)

代码隐藏:

//MainPage.xaml.cs:

using Windows.UI.Xaml.Controls;

namespace BrokenListSample
{
    public sealed partial class MainPage : Page
    {
        public MainPageViewModel ViewModel { get; set; }

        public MainPage()
        {
            InitializeComponent();
            DataContextChanged += (s, e) => { ViewModel = DataContext as MainPageViewModel; };
            DataContext = new MainPageViewModel();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

最后是ViewModel:

//MainPageViewModel.cs:

using System.Collections.ObjectModel;
using System.ComponentModel;

namespace BrokenListSample
{
    public class MainPageViewModel : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        public void OnPropertyChanged(string name)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
        }

        private ObservableCollection<string> _myItems;
        public ObservableCollection<string> MyItems
        {
            get { return _myItems; }
            set { _myItems = value; OnPropertyChanged("MyItems"); }
        }

        private string _bestItem;
        public string BestItem
        {
            get { return _bestItem; }
            set { _bestItem = value; OnPropertyChanged("BestItem"); }
        }

        public MainPageViewModel()
        {
            MyItems = new ObservableCollection<string>() { "One", "Two", "Three", "Four" };
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

如您所见,我的MainPage上有两个ListView控件.如果您尝试运行此代码,请根据您要检查的绑定类型对其中一个进行评论.第二行的ListView使用旧的好Binding,它只是简单的工作.这里不足为奇.

惊喜来自于使用新的x:Bind导致StackOverflowException.使用OneWay模式可以正常工作 - 但只要我点击其中一个项目,TwoWay就会抛出StackOverflowException ...搞笑......

我的问题很简单 - "为什么以及如何解决这个问题?"

Iur*_*ena 4

我面临着同样的问题。查看堆栈跟踪,我发现我的列表视图正在修改视图模型,即引发 OnPropertyChanged,从而修改列表视图...要解决这个问题,您应该修改绑定属性的设置器:

public string BestItem
{
  get { return _bestItem; }
  set
  {
    if (_bestItem != value)
    {
      _bestItem = value;
      OnPropertyChanged(nameof(BestItem));
    }
  }
}
Run Code Online (Sandbox Code Playgroud)