2015-11-22 11 views
5

बाध्यकारी के माध्यम से सेटिंग से लोड किए गए CombBox चयनित आइटम को प्रतिबिंबित करता है यह an earlier question से एक निरंतरता है।यूडब्लूपी

कुछ ऐप सेटिंग्स के लिए मैं एक विकल्प चुनने के लिए कॉम्बोबॉक्स का उपयोग करना चाहता हूं। मैं चयनित विकल्प को (रोमिंग) सेटिंग्स में सहेज सकता हूं और इसे फिर से लोड कर सकता हूं। भारित विकल्प टेक्स्टब्लॉक में ठीक से प्रदर्शित होता है लेकिन कॉम्बोबॉक्स एक खाली दिखाता है। मैं कॉम्बोबॉक्स में वर्तमान में चुने गए विकल्प को लोड कैसे कर सकता हूं?

यह XAML है:

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

<Page.Resources> 
    <converter:ComboBoxItemConvert x:Key="ComboBoxItemConvert" /> 
</Page.Resources> 


<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"> 
    <StackPanel> 
     <ComboBox 
      Name="ComboBox" 
      ItemsSource="{x:Bind ComboBoxOptions}" 
      SelectedItem="{x:Bind SelectedComboBoxOption, Mode=TwoWay, Converter={StaticResource ComboBoxItemConvert}}" 
      SelectedValuePath="ComboBoxOption" 
      DisplayMemberPath="ComboBoxHumanReadableOption" 
      Header="ComboBox" > 
     </ComboBox> 
     <TextBlock Name="BoundTextblock" Text="{x:Bind SelectedComboBoxOption.ComboBoxOption, Mode=OneWay}"/> 
    </StackPanel> 
</Grid> 

और इसके पीछे कोड है:

using System; 
using System.Collections.Generic; 
using System.Collections.ObjectModel; 
using System.ComponentModel; 
using System.IO; 
using System.Linq; 
using System.Runtime.InteropServices.WindowsRuntime; 
using System.Xml.Serialization; 
using Windows.Foundation; 
using Windows.Foundation.Collections; 
using Windows.Storage; 
using Windows.UI.Xaml; 
using Windows.UI.Xaml.Controls; 
using Windows.UI.Xaml.Controls.Primitives; 
using Windows.UI.Xaml.Data; 
using Windows.UI.Xaml.Input; 
using Windows.UI.Xaml.Media; 
using Windows.UI.Xaml.Navigation; 

// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x409 

namespace ComboBoxTest 
{ 
/// <summary> 
/// An empty page that can be used on its own or navigated to within a Frame. 
/// </summary> 
public sealed partial class MainPage : Page, INotifyPropertyChanged 
{ 
    ApplicationDataContainer roamingSettings = null; 

    private ObservableCollection<ComboBoxItem> ComboBoxOptions; 

    public MainPage() 
    { 
     this.InitializeComponent(); 
     ComboBoxOptions = new ObservableCollection<ComboBoxItem>(); 
     ComboBoxOptionsManager.GetComboBoxList(ComboBoxOptions); 


     roamingSettings = ApplicationData.Current.RoamingSettings; 


     var value = (string)roamingSettings.Values["ComboBoxSelection"]; 
     if (value != null) 
     { 
      SelectedComboBoxOption = Deserialize<ComboBoxItem>(value); //loaded selection reflected in the textbox but not in the ComboBox 
     } 
     else 
     { 
      SelectedComboBoxOption = ComboBoxOptions[0]; 
     } 

    } 

    public class ComboBoxItem 
    { 
     public string ComboBoxOption { get; set; } 
     public string ComboBoxHumanReadableOption { get; set; } 
    } 

    public class ComboBoxOptionsManager 
    { 
     public static void GetComboBoxList(ObservableCollection<ComboBoxItem> ComboBoxItems) 
     { 
      var allItems = getComboBoxItems(); 
      ComboBoxItems.Clear(); 
      allItems.ForEach(p => ComboBoxItems.Add(p)); 
     } 

     private static List<ComboBoxItem> getComboBoxItems() 
     { 
      var items = new List<ComboBoxItem>(); 

      items.Add(new ComboBoxItem() { ComboBoxOption = "Option1", ComboBoxHumanReadableOption = "Option 1" }); 
      items.Add(new ComboBoxItem() { ComboBoxOption = "Option2", ComboBoxHumanReadableOption = "Option 2" }); 
      items.Add(new ComboBoxItem() { ComboBoxOption = "Option3", ComboBoxHumanReadableOption = "Option 3" }); 

      return items; 
     } 
    } 

    private ComboBoxItem _SelectedComboBoxOption; 

    public ComboBoxItem SelectedComboBoxOption 
    { 
     get 
     { 
      return _SelectedComboBoxOption; 
     } 
     set 
     { 
      if (_SelectedComboBoxOption != value) 
      { 
       _SelectedComboBoxOption = value; 
       roamingSettings.Values["ComboBoxSelection"] = Serialize(value); 
       RaisePropertyChanged("SelectedComboBoxOption"); 
      } 
     } 
    } 




    public static string Serialize(object obj) 
    { 
     using (var sw = new StringWriter()) 
     { 
      var serializer = new XmlSerializer(obj.GetType()); 
      serializer.Serialize(sw, obj); 
      return sw.ToString(); 
     } 
    } 

    public static T Deserialize<T>(string xml) 
    { 
     using (var sw = new StringReader(xml)) 
     { 
      var serializer = new XmlSerializer(typeof(T)); 
      return (T)serializer.Deserialize(sw); 
     } 
    } 


    void RaisePropertyChanged(string prop) 
    { 
     if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(prop)); } 
    } 
    public event PropertyChangedEventHandler PropertyChanged; 
} 
} 

उत्तर

6

यह आइटम है कि एक ही लग रही है, लेकिन जब से नहीं कर रहे हैं की एक विशिष्ट मामले उनके पास अलग-अलग संदर्भ हैं (C# reference types पर पढ़ें)।

आप ComboBox को 3 मानों के साथ लोड करते हैं और ये 3 मान ड्रॉपडाउन में दिखाए जाते हैं। ComboBox बंद होने पर एक चयनित आइटम देखने के लिए, यह इन 3 मानों में से एक (= जैसा ही संदर्भ है) होना चाहिए। जब आपके रोमिंग सेटिंग्स में कुछ भी नहीं बचा है, तो आप पहले को SelectedItem के रूप में चुनें। किसी अन्य चयनित आइटम पर स्विचिंग, आपके पास SelectedItem संपत्ति में एक वैध संदर्भ भी होगा।

हालांकि जब आप सहेजे गए RoamingSettings मान को deserialize करते हैं, तो आप एक अलग संदर्भ के साथ एक नई वस्तु बनाते हैं। जब आप इस आइटम को SelectedItem के रूप में सेट करते हैं, तो ComboBox नियंत्रण इसे अपने आइटम में नहीं मिलेगा और इस प्रकार कोई आइटम नहीं चुनता है।

इसे ठीक करने के लिए आपको ItemSource संग्रह में सही मद को ढूंढना होगा:

var value = (string)roamingSettings.Values["ComboBoxSelection"]; 
if (value != null) 
{ 
    var deserialized = Deserialize<ComboBoxItem>(value); 
    // using ComboBoxOption as the primary key field of your object 
    SelectedComboBoxOption = ComboBoxOptions.SingleOrDefault(c => 
       c.ComboBoxOption == deserialized.ComboBoxOption); 
} 
else 
{ 
    SelectedComboBoxOption = ComboBoxOptions[0]; 
} 
संबंधित मुद्दे