代码之家  ›  专栏  ›  技术社区  ›  Andrew Truckle

为什么我与拾取器的绑定无法使用xaml/xamarin?

  •  0
  • Andrew Truckle  · 技术社区  · 4 年前

    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属性。 选择器默认为现有值。

    0 回复  |  直到 4 年前
        1
  •  0
  •   Andrew Truckle    4 年前

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

    XAML

    我换了 Binding 在XAML中,如下所示 Picker :

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

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

    代码背后

    我删除了 public ObservableCollection<string> StylesList { get; set; } 从这个班。

    查看模型

    我贴了上面提到的 StylesList 物业并在 ElderlyInfirmViewModel 建设者。

    这个 Style 房地产在 VisitsRotaData 类。


    样品

    现在,当我的窗口显示时 选择器 默认值为XML文件中的值: enter image description here

    我想我让事情变得复杂了 ItemSource 代码隐藏 以及 SelectedItem 视图模型 通过将所有内容保存在一个地方( 绑定上下文 页面)它工作。