XF UWP - MVVM - 如何在嵌套对象中绑定选取器选定项?

Posted

技术标签:

【中文标题】XF UWP - MVVM - 如何在嵌套对象中绑定选取器选定项?【英文标题】:XF UWP - MVVM - How to bind Picker selected item in a Nested Object? 【发布时间】:2021-07-23 16:03:41 【问题描述】:

我无法根据 Picker SelectedItem 更改对象,但我可以更改该对象的属性。我没看到什么?

我尝试将继承 ObservableCollections 的对象更改为将 ObservableCollections 作为属性并改为继承 PropertyChanged,但属性仍未注册更改。

XAML 绑定失败为空。

页面 XAML:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:viewmodel="clr-namespace:ItemSourceBug.ViewModel"
             x:Class="ItemSourceBug.Views.MainPage"
             x:Name="MPage">
    <ContentPage.BindingContext>
        <viewmodel:MainViewModel/>
    </ContentPage.BindingContext>
    
    <StackLayout BindableLayout.ItemsSource="Binding model.CurrentControlList"
                 VerticalOptions="Center">
        <BindableLayout.ItemTemplate>
            <DataTemplate>
                <StackLayout BindableLayout.ItemsSource="Binding .">
                    <BindableLayout.ItemTemplate>
                        <DataTemplate>
                            <StackLayout>
                                <Label Text="Binding typeAction"/>
                                <StackLayout BindableLayout.ItemsSource="Binding .">
                                    <BindableLayout.ItemTemplate>
                                        <DataTemplate>
                                            <StackLayout Orientation="Horizontal">
                                                <Label Text="Binding name"/>
                                                <Label Text="Binding type"/>
                                                <Picker ItemsSource="Binding Path=BindingContext.model.SelectFromList, 
                                                                    Source=x:Reference MPage"
                                                        ItemDisplayBinding="Binding name"
                                                        SelectedItem="Binding "> <!--This doesn't work-->                                                   
                                                </Picker>
                                                <Picker SelectedItem="Binding type"> <!--This works-->
                                                    <Picker.Items>
                                                        <x:String>3</x:String>
                                                        <x:String>4</x:String>
                                                        <x:String>5</x:String>
                                                    </Picker.Items>
                                                </Picker>
                                                <Label Text="Binding Path=BindingContext.model.currentAction.name, Source=x:Reference MPage"/>
                                                <Picker ItemsSource="Binding Path=BindingContext.model.SelectFromList, 
                                                                    Source=x:Reference MPage"
                                                        ItemDisplayBinding="Binding name"
                                                        SelectedItem="Binding Path=BindingContext.model.currentAction, Source=x:Reference MPage"> <!--This works-->
                                                    </Picker>            
                                            </StackLayout>
                                        </DataTemplate>
                                    </BindableLayout.ItemTemplate>
                                </StackLayout>
                            </StackLayout>
                        </DataTemplate>
                    </BindableLayout.ItemTemplate>
                </StackLayout>
            </DataTemplate>
        </BindableLayout.ItemTemplate>               
    </StackLayout>
</ContentPage>

页面视图模型:

using ItemSourceBug.Model;
using System;
using System.Collections.Generic;
using System.Text;
using Xamarin.Forms;

namespace ItemSourceBug.ViewModel

    public class MainViewModel : BaseViewModel
    
        #region Properties
        public MainModel model  get; set;  = new MainModel();
        #endregion


        #region Commands

        #endregion
    

页面模型:

using ItemSourceBug.ViewModel;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Text;

namespace ItemSourceBug.Model

    public class MainModel: BaseViewModel
    

        #region Properties
        public ControlList CurrentControlList  get; set;  = new ControlList();

        public Action currentAction  get; set;  = new Action  id = "6", name = "Leon" ;
        public Actions SelectFromList  get; set;  = new Actions();
        #endregion

        #region Constructor
        public MainModel()
        
            SelectFromList.Add(new Action  id = "1239", name="George" );
            SelectFromList.Add(new Action  id = "1240", name = "Mike" );
        
        #endregion
    

    public class ControlList : ObservableCollection<TaskActions> 
     
        public string typeControl  get; set; 
        public ControlList()
        
            Add(new TaskActions  typeTask = "observ" );
            Add(new TaskActions  typeTask = "discuss" );
        
    


    public class TaskActions : ObservableCollection<Actions>
    
        public string typeTask  get; set; 
        public TaskActions()
        
            Add(new Actions  typeAction = "sing" );
            Add(new Actions  typeAction = "dance" );
        
    

    public class Actions: ObservableCollection<Action>
    
        public string typeAction  get; set; 
         public Actions()
        
            Add(new Action  id = "1231" , name = "John" );
            Add(new Action  id = "1232", name = "Jane" );
            Add(new Action  id = "1237", name = "Joseph" );
            Add(new Action  id = "1238", name = "Jimbo" );
        
    

    public class Action: BaseViewModel
    
        public string id  get; set; 
        public string name  get; set; 
        public string type  get; set;  = "1";
        /*
        public override string ToString()
        
            return name;
        
        */
    


【问题讨论】:

【参考方案1】:

您应该在Label.TextPicker.SelectedItem + Picker.ItemDisplayBinding 上保持相同的绑定路径。

在您的代码中

第一个:

MPage.BindingContext.model.SelectFromList.name != model.CurrentControlList.x.x.name,它们是不同的东西,所以它不起作用。


第二个:

type = type,所以它可以工作。


第三个:

MPage.BindingContext.model.currentAction.name = MPage.BindingContext.model.currentAction.name ,所以它可以工作。

【讨论】:

首先...为什么这些对象不同?它们都是“动作”。我找到了一个解决方法,我会在一分钟内提出,但我想知道为什么它们不是要在 SelectedItem 上设置的相同对象?【参考方案2】:

我发现的解决方法是改变:

动作类:

    public class Action: INotifyPropertyChanged
    
        public string id  get; set; 
        public string name  get; set; 
public Action instance  get; set; 
        public string type  get; set;  = "1";
        /*
        public override string ToString()
        
            return name;
        
        */

//Reedited:
public Action()

instance = this;


        #region INotifyPropertyChanged
        public event PropertyChangedEventHandler PropertyChanged;
        protected void OnPropertyChanged([CallerMemberName] string propertyName = "")
        
            var changed = PropertyChanged;
            if (changed == null)
                return;

            if (propertyName.Equals("instance"))
            
                name = instance.name;
                id = instance.id;
                type = instance.type;
            

            changed.Invoke(this, new PropertyChangedEventArgs(propertyName));
        
        #endregion
    

我的 XAML 文件中的 Picker 为:

<Picker ItemsSource="Binding Path=BindingContext.model.SelectFromList, 
                    Source=x:Reference MPage"
        ItemDisplayBinding="Binding name"
        Grid.Column="2"
        SelectedItem="Binding instance,Mode=TwoWay"
        >                                                  
</Picker>

【讨论】:

以上是关于XF UWP - MVVM - 如何在嵌套对象中绑定选取器选定项?的主要内容,如果未能解决你的问题,请参考以下文章

如何通过在 AngularJS 中绑定来捕获来自无效属性的 html 编译错误

C#UWP填充和访问嵌套列表

在 mvvm 中为 uwp 分享 inkCanvas 问题

在 UWP 应用程序中,如何防止 Gamepad 也移动插入符号?

win10 uwp MVVM入门

UWP 绑定到 MVVM 中的 AutoSuggestBox