【问题标题】:Why is my binding to my picker not working with xaml/xamarin?为什么我的选择器绑定不能与 xaml/xamarin 一起使用?
【发布时间】:2021-05-16 14:24:49
【问题描述】:

XAML Xamarin 5 - MacOS

XAML:

<Picker x:Name="StylesPicker" Title="Select stylesheet" HorizontalOptions="FillAndExpand" SelectedIndexChanged="StylesPicker_SelectedIndexChanged" SelectedItem="{Binding Path=vrrData.Style, Mode=TwoWay}"/>

后面的代码:

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using AppKit;
using VisitsRota.ViewModels;
using Xamarin.Essentials;
using Xamarin.Forms;

namespace VisitsRota.Views
{
    public partial class ElderlyInfirmPage : ContentPage
    {
        public ObservableCollection<string> StylesList { get; set; }

        public ElderlyInfirmPage()
        {
            InitializeComponent();
            BindingContext = new ElderlyInfirmViewModel();

            string[] stylesArray = Directory.GetFiles("/Users/Shared/VisitsRota.MacOS/Styles", "ElderlyInfirm-Schedule-*.xsl")
                                      .Select(file => Path.GetFileName(file)).ToArray<string>();
            StylesList = new ObservableCollection<string>(stylesArray);
            StylesPicker.ItemsSource = StylesList;
     
        }    

        async private void InstallStyleButton_Clicked(object sender, EventArgs e)
        {
            var customFileType =
                new FilePickerFileType(new Dictionary<DevicePlatform, IEnumerable<string>>
                {
                    {DevicePlatform.macOS, new[] {"xsl"} }
                });

            var pickResult = await FilePicker.PickAsync(new PickOptions
            {
                FileTypes = customFileType,
                PickerTitle = "Select template to install"

            });

            if(pickResult != null)
            {
                StylesList.Add(pickResult.FileName);
            }
        }

        void StylesPicker_SelectedIndexChanged(System.Object sender, System.EventArgs e)
        {
            var picker = (Picker)sender;
            int selectedIndex = picker.SelectedIndex;

            if(selectedIndex != -1)
            {
                string x =   (string)picker.ItemsSource[selectedIndex];
            }
        }
    }
}

查看模型:

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Xml.Serialization;

namespace VisitsRota.ViewModels
{
    public class ElderlyInfirmViewModel : BaseViewModel
    {
        public List<string> StylesList { get; set; }
        public List<string> ListMonths { get; }
        public VisitsRotaData vrrData { get; set; }

        public ElderlyInfirmViewModel()
        {
            vrrData = DeserializeFromXml<VisitsRotaData>("/Users/Shared/VisitsRota.MacOS/VisitsRotaData.xml");

            // Should this list be private?
            ListMonths = DateTimeFormatInfo.CurrentInfo.MonthNames.TakeWhile(m => m != String.Empty).ToList();

            StylesList = Directory.GetFiles("/Users/Shared/VisitsRota.MacOS/Styles", "ElderlyInfirm-Schedule-*.xsl")
                                      .Select(file => Path.GetFileName(file)).ToList<string>();

                
        }

        public T DeserializeFromXml<T>(string filePath)
        {
            try
            {
                if (!System.IO.File.Exists(filePath))
                    throw new ArgumentNullException(filePath + " not Exists");
                using (System.IO.StreamReader reader = new System.IO.StreamReader(filePath))
                {
                    System.Xml.Serialization.XmlSerializer xs = new System.Xml.Serialization.XmlSerializer(typeof(T));
                    T ret = (T)xs.Deserialize(reader);
                    return ret;
                }
            }
            catch (Exception ex)
            {
                return default(T);
            }
        }

    }
   
    [XmlType(TypeName="VisitsRotaData")]
    public class VisitsRotaData : BaseViewModel
    {

        private ObservableCollection<string> _listelders;
        private ObservableCollection<string> _listpublishers;
        private string _style;

        [XmlArray("Elders")]
        [XmlArrayItem("Elder")]
        public ObservableCollection<string> ListElders
        {
            get { return _listelders; }
            set {
                _listelders = value;
                OnPropertyChanged("ListElders");
            }
        }

        [XmlArray("Publishers")]
        [XmlArrayItem("Publisher")]
        public ObservableCollection<string> ListPublishers
        {
            get { return _listpublishers; }
            set
            {
                _listpublishers = value;
                OnPropertyChanged("ListPublishers");
            }
        }

        [XmlElement]
        public string Style
        {
            get { return _style; }
            set
            {
                _style = value;
                OnPropertyChanged("Style");
            }
        }
    }
}

XML 数据:

<?xml version="1.0" encoding="UTF-8" ?>
<VisitsRotaData>
    <Elders>
        <Elder>Elder 1</Elder>
        <Elder>Elder 2</Elder>
        <Elder>Elder 3</Elder>
        <Elder>Elder 4</Elder>
        <Elder>Elder 5</Elder>
        <Elder>Elder 6</Elder>
        <Elder>Elder 7</Elder>
        <Elder>Elder 8</Elder>
    </Elders>
    <Publishers>
       <Publisher>Publisher 1</Publisher>
       <Publisher>Publisher 2</Publisher>
       <Publisher>Publisher 3</Publisher>
       <Publisher>Publisher 4</Publisher>
       <Publisher>Publisher 5</Publisher>
       <Publisher>Publisher 6</Publisher>
       <Publisher>Publisher 7</Publisher>
       <Publisher>Publisher 8</Publisher>
       <Publisher>Publisher 9</Publisher>
       <Publisher>Publisher 10</Publisher>
    </Publishers>
    <Style>ElderlyInfirm-Schedule-v2.xsl</Style>
</VisitsRotaData>

选取器会填充文件夹中的文件。没事儿。但是当窗口显示时,它选择了选择器中的第一项,而不是第二项(这是 Styles 的值。

预期行为:

将 Picker 的值绑定到 Styles 属性。 选择器默认为现有值。

【问题讨论】:

    标签: xaml xamarin.forms binding picker


    【解决方案1】:

    看来我已经解决了。 ? 这个答案here 为我指明了正确的方向。

    XAML

    我将 XAML 中的 Binding 更改为 Picker

    <Picker x:Name="StylesPicker" Title="Select stylesheet" 
            HorizontalOptions="FillAndExpand" 
            ItemsSource="{Binding StylesList}" 
            SelectedItem="{Binding Path=vrrData.Style, Mode=TwoWay}"/>
    

    如您所见,我还删除了StylesPicker_SelectedIndexChanged 处理程序。

    代码隐藏

    我从这个类中删除了public ObservableCollection&lt;string&gt; StylesList { get; set; }

    查看模型

    我粘贴了上述StylesList 属性并将其填充到ElderlyInfirmViewModel 构造函数中。

    Style 属性在 VisitsRotaData 类中保持不变。


    样本

    现在,当我的窗口显示时,Picker 默认为我的 XML 文件中的值:

    我认为我在 代码后面 中使用 ItemSource 并在 视图模型 中使用 SelectedItem 使其复杂化。通过将所有内容保存在一个位置(页面的 BindingContext),它可以正常工作。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-09-20
      • 2018-01-07
      • 1970-01-01
      • 2015-08-26
      • 2021-02-01
      • 2020-05-22
      • 2016-04-10
      相关资源
      最近更新 更多