【问题标题】:UWP Gridview Binding to ObservableCollection and clearing valuesUWP Gridview 绑定到 ObservableCollection 并清除值
【发布时间】:2016-12-07 16:33:14
【问题描述】:

所以我在绑定到 ObservableCollection 的 UWP 应用程序中创建 GridView。

XAML:

<Page.Resources>
    <CollectionViewSource
            x:Name="ListSource"
            Source="{x:Bind model.ShowList}"
            IsSourceGrouped="false"
            />
</Page.Resources>
...
<Page>
    <GridView x:Name="lvListSource" ItemsSource="{Binding Source={StaticResource ListSource}}" SelectedIndex="-1" Grid.Row="2" HorizontalContentAlignment="Center" SelectionChanged="lvEpisodeListSource_SelectionChanged">
                <GridView.ItemTemplate>
                    <DataTemplate x:DataType="local:PageInput">
                        <TextBlock Name="AlbumBlock" Foreground="Black" FontWeight="Normal" FontSize="15" Margin="5,0,5,0"
                                    Text="{x:Bind Name}" HorizontalAlignment="Left" VerticalAlignment="Center" Width="100"/>
                    </DataTemplate>
                </GridView.ItemTemplate>
            </GridView>
</page>

C#:

public MainCategoryModel model;
public MainPage()
{
    model = new MainCategoryModel();
    this.InitializeComponent();
}

protected override void OnNavigatedTo(NavigationEventArgs e)
{
    //initialize model data in code and stuff comes out correctly
    //model.Clear() give unknown error here
    model.Add(new PageInput() {...});
    lvListSource.ItemsSource = model.myList;
}

public class MainCategoryModel
{
    public ObservableCollection<PageInput> myList { get; set; }

    public MainCategoryModel()
    {
        myList = new ObservableCollection<PageInput>();
    }

    public void AddShow(PageInput show)
    {
        myList.Insert(0, show);
    }

    public void Clear()
    {
        myList.Clear();
    }
}

当我只向集合中添加项目时,ObservableCollection 正确初始化并且页面加载非常好。问题是,我想在每次调用 OnNavigatedTo 函数时更新 GridView 绑定的 ObservableCollection。这包括从集合中删除项目。每次我删除项目或尝试清除 ObservableCollection 时,页面都无法加载并出现未知错误。有没有办法从已绑定的 Observable Collection 中修改和删除值?

作为一个附带问题,如果我没有在 OnNavigatedTo 的末尾重新设置 ItemsSource 属性,则在向 Collection 添加值后会立即调用 SelectionChanged 事件,因为它是在 XAML 中设置的。有没有办法在将项目添加到 GridView 时不调用 SelectionChanged 事件?

【问题讨论】:

    标签: c# gridview uwp


    【解决方案1】:

    x:Bind 默认为 OneTime,需要设置 Mode=OneWay 才能获取布局更新

       protected override void OnNavigatedTo(NavigationEventArgs e)
       {
           //initialize model data in code and stuff comes out correctly
    
          lvEpisodeListSource.ItemsSource = model.myList;
       }
    

    杀死你的绑定,更新 model.myList 并让绑定完成这项工作,如果你希望它被绑定,请不要以这种方式从代码中设置 ItemsSource

    编辑:

    复制并运行您的代码(这不是愉快的体验,因为您没有将其清理干净),我不明白为什么您的代码中的 Binding 和 x:Bind 如此混乱,为什么不你就这样绑定集合?

    <GridView x:Name="lvListSource" ItemsSource="{x:Bind model.myList, Mode=OneWay}" ....
    

    编辑2:

    我的代码:

    public class MainCategoryModel
    {
        public ObservableCollection<PageInput> myList { get; set; }
    
        public MainCategoryModel()
        {
            myList = new ObservableCollection<PageInput>();
        }
    
        public void AddShow(PageInput show)
        {
            myList.Insert(0, show);
        }
    
        public void Clear()
        {
            myList.Clear();
        }
    }
    
    <Page>
    (........)
        <GridView x:Name="lvListSource" ItemsSource="{x:Bind model.myList, Mode=OneWay}" SelectedIndex="-1" Grid.Row="2" HorizontalContentAlignment="Center">
        <GridView.ItemTemplate>
            <DataTemplate x:DataType="local:PageInput">
                <TextBlock Name="AlbumBlock" Foreground="Black" FontWeight="Normal" FontSize="15" Margin="5,0,5,0"
                                    Text="{x:Bind Name}" HorizontalAlignment="Left" VerticalAlignment="Center" Width="100"/>
            </DataTemplate>
        </GridView.ItemTemplate>
    </GridView>
    

    public sealed partial class MainPage : Page
    {
        public MainCategoryModel model;
        public MainPage()
        {
            model = new MainCategoryModel();
            this.InitializeComponent();
        }
    
        protected override void OnNavigatedTo(NavigationEventArgs e)
        {
            model.Clear();
            model.myList.Add(new PageInput() {Name = "testName"});
        }
    

    }

    由 quests 制作:

    public class PageInput
    {
        public string Name { get; set; }
    }
    

    尝试运行并检查它

    【讨论】:

    • 如果我删除它,但当我尝试从集合中删除一个项目时,我仍然遇到同样的崩溃问题。如果我没有添加项目,它还会在我添加项目时自动调用我的 SelectionChanged 事件。
    • 获取您的代码并使其可运行,请检查编辑
    • 您好,绑定效果很好!不知道你可以那样做。这一切都在第一次运行时完美运行,但每个项目都有一个 SelectionChanged 事件,该事件调用另一个页面。在编辑中为您添加。当我使用内置的应用程序后退按钮时,我在点击 Clear() 函数时收到未处理的 XAML 错误。
    • 抱歉这么难!非常感谢您的帮助!因此,如果您从此处导航到另一个页面,然后导航回 MainPage,则 OnNavigated 中的 Clear 函数会导致未处理的 XAML 异常。
    • @kennywitham 我无法重现此问题。你能分享一下minimal reproducible example吗?
    【解决方案2】:

    当打开页面缓存时,清除 XAML 代码绑定到的数据对象会产生未知错误。禁用页面缓存可让您正确清除对象。

    this.NavigationCacheMode = NavigationCacheMode.Disabled;
    

    这是社区中已有的example

    【讨论】:

    • 您附加的链接实际上是指向当前线程的。那么如果我们想在导航到缓存页面时清除 ObservableCollection 怎么办?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-04
    相关资源
    最近更新 更多