2

WPFでCheckedListBoxを構築し、それをユーザー設定にバインドして、一度だけ構築され、XAMLで設定を自動的に更新しようとしています。ListBox ItemsSource="{Binding Source={x:Static local:Settings.Default}, Path=Customers, Mode=TwoWay}

チェックボックスは表示されますが、顧客名が表示されず、設定に値が保持されません。誰かがその理由を見つけることができますか?

設定から現在のCustomersObservableCollectionにキャストする必要があると思いますが、これを機能させることはできませんか?

Customers = Properties.Settings.Default.Customers.Cast;

TestSettings.xaml

<Window x:Class="WpfApplication1.TestSettings"
        xmlns:local="clr-namespace:WpfApplication1.Properties"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="TestSettings" Height="300" Width="300">
    <Grid>
    <ListBox ScrollViewer.VerticalScrollBarVisibility="Auto" ItemsSource="{Binding Source={x:Static local:Settings.Default}, Path=Customers, Mode=TwoWay}" Margin="12,22,12,79">
        <ListBox.ItemTemplate>
            <DataTemplate>
                <CheckBox IsChecked="{Binding IsChecked}" Content="{Binding Path=Item.CustomerName}" />
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>
    </Grid>
</Window>

TestSettings.xaml.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.ComponentModel;
using System.Collections.ObjectModel;

namespace WpfApplication1
{
    /// <summary>
    /// Interaction logic for TestSettings.xaml
    /// </summary>
    public partial class TestSettings : Window
    {

        public ObservableCollection<CheckedListItem<Customer>> Customers { get; set; }

        public class Customer
        {
            public string CustomerName { get; set; }
        }

        public TestSettings()
        {
            InitializeComponent();

            if (Properties.Settings.Default.Customers == null)
            {
                Properties.Settings.Default.Customers = new ObservableCollection<Customer> 
                { 
                        new Customer() { CustomerName = "Kelly Smith" },
                        new Customer() { CustomerName = "Joe Brown" },
                        new Customer() { CustomerName = "Herb Dean" }

                    //Customers.Add(new CheckedListItem<Customer>(new Customer(){CustomerName="Kelly Smith"}));
                    //Customers.Add(new CheckedListItem<Customer>(new Customer(){CustomerName="Joe Brown"}));
                    //Customers.Add(new CheckedListItem<Customer>(new Customer(){CustomerName="Herb Dean"}));

                };
                Properties.Settings.Default.Save();
            }
            else
            {
               // Customers = (ObservableCollection<Customer>)Properties.Settings.Default.Customers;
            }
        }

        public class CheckedListItem<T> : INotifyPropertyChanged
        {
            public event PropertyChangedEventHandler PropertyChanged;

            private bool isChecked;
            private T item;

            public CheckedListItem()
            { }

            public CheckedListItem(T item, bool isChecked = false)
            {
                this.item = item;
                this.isChecked = isChecked;
            }

            public T Item
            {
                get { return item; }
                set
                {
                    item = value;
                    if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs("Item"));
                }
            }


            public bool IsChecked
            {
                get { return isChecked; }
                set
                {
                    isChecked = value;
                    if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs("IsChecked"));
                }
            }
        }

        private void Window_Closing(object sender, CancelEventArgs e)
        {
            Properties.Settings.Default.Save();
        }
    }
}

Settings.Designer.cs

//------------------------------------------------------------------------------
// <auto-generated>
//     This code was generated by a tool.
//     Runtime Version:4.0.30319.269
//
//     Changes to this file may cause incorrect behavior and will be lost if
//     the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------

using System.Collections.ObjectModel;
namespace WpfApplication1.Properties
{


    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "10.0.0.0")]
    internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase
    {

        private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));

        public static Settings Default
        {
            get
            {
                return defaultInstance;
            }

        }

        [global::System.Configuration.UserScopedSettingAttribute()]
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
        public ObservableCollection<WpfApplication1.TestSettings.Customer> Customers
        {
            get
            {
                return ((ObservableCollection<WpfApplication1.TestSettings.Customer>)(this["Customers"]));
            }
            set
            {
                this["Customers"] = value;
            }
        }

    }
}
4

1 に答える 1

0

OK-ソート済み。

2つの主な問題がありました

1 / CheckListItemではなくCustomerNameのみを追加していたので、

ObservableCollection<Customer> する必要がありますObservableCollection<CheckedListItem<Customer>>

2/同じように顧客を追加します。

new Customer() { CustomerName = "Kelly Smith" }する必要がありますnew CheckedListItem<Customer>(new Customer() { CustomerName = "Kelly Smith" })

したがって、完全に機能するコードは

Settings.Designer.cs

using System.Collections.ObjectModel;
namespace WpfApplication1.Properties {


    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "10.0.0.0")]
    internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {

        private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));

        public static Settings Default {
            get {
                return defaultInstance;
            }
        }

        [global::System.Configuration.UserScopedSettingAttribute()]
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
        public ObservableCollection<WpfApplication1.TestSettings.CheckedListItem<WpfApplication1.TestSettings.Customer>> Customers
        {
            get
            {
                return ((ObservableCollection<WpfApplication1.TestSettings.CheckedListItem<WpfApplication1.TestSettings.Customer>>)(this["Customers"]));
            }
            set
            {
                this["Customers"] = value;
            }
        }
    }
}

TestSettings.xaml

<Window x:Class="WpfApplication1.TestSettings"
        xmlns:local="clr-namespace:WpfApplication1.Properties"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="TestSettings" Height="300" Width="300" Closing="Window_Closing">
    <Grid>
        <ListBox ScrollViewer.VerticalScrollBarVisibility="Auto" ItemsSource="{Binding Source={x:Static local:Settings.Default}, Path=Customers, Mode=TwoWay}" Margin="12,22,12,79">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <CheckBox IsChecked="{Binding IsChecked}" Content="{Binding Path=Item.CustomerName}" />
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
    </Grid>
</Window>

TestSettings.xaml.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.ComponentModel;
using System.Collections.ObjectModel;

namespace WpfApplication1
{
    /// <summary>
    /// Interaction logic for TestSettings.xaml
    /// </summary>
    public partial class TestSettings : Window
    {

        public ObservableCollection<CheckedListItem<Customer>> Customers
        {
            get;
            set;
        }


        public class Customer
        {
            public string CustomerName { get; set; }
        }

        public TestSettings()
        {
            InitializeComponent();

            if (Properties.Settings.Default.Customers == null)
            {
                Properties.Settings.Default.Customers = new ObservableCollection<CheckedListItem<Customer>>
                { 
                        new CheckedListItem<Customer>(new Customer() { CustomerName = "Kelly Smith" }),
                        new CheckedListItem<Customer>(new Customer() { CustomerName = "Joe Brown" }),
                        new CheckedListItem<Customer>(new Customer() { CustomerName = "Herb Dean" }),
                        new CheckedListItem<Customer>(new Customer() { CustomerName = "fg4" }),
                        new CheckedListItem<Customer>(new Customer() { CustomerName = "fg5" }),
                        new CheckedListItem<Customer>(new Customer() { CustomerName = "fg6" }),
                        new CheckedListItem<Customer>(new Customer() { CustomerName = "fg7" }),
                        new CheckedListItem<Customer>(new Customer() { CustomerName = "fg8" }),
                        new CheckedListItem<Customer>(new Customer() { CustomerName = "fg9" }),
                        new CheckedListItem<Customer>(new Customer() { CustomerName = "fg10" }),
                        new CheckedListItem<Customer>(new Customer() { CustomerName = "fg11" }),
                        new CheckedListItem<Customer>(new Customer() { CustomerName = "fg12" }),
                        new CheckedListItem<Customer>(new Customer() { CustomerName = "fg13" }),
                        new CheckedListItem<Customer>(new Customer() { CustomerName = "fg14" })

                };
                Properties.Settings.Default.Save();

            }
            else
            {
                //var a = Properties.Settings.Default.Customers;
                //Customers = ObservableCollection<CheckedListItem<>>;

            }
        }

        public class CheckedListItem<T> : INotifyPropertyChanged
        {
            public event PropertyChangedEventHandler PropertyChanged;

            private bool isChecked;
            private T item;

            public CheckedListItem()
            { }

            public CheckedListItem(T item, bool isChecked = false)
            {
                this.item = item;
                this.isChecked = isChecked;
            }

            public T Item
            {
                get { return item; }
                set
                {
                    item = value;
                    if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs("Item"));
                }
            }


            public bool IsChecked
            {
                get { return isChecked; }
                set
                {
                    isChecked = value;
                    if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs("IsChecked"));
                }
            }
        }

        private void Window_Closing(object sender, CancelEventArgs e)
        {
            Properties.Settings.Default.Save();
        }
    }
}

編集:これは機能するようですが、Settings.Designer.cs修正されているため、ジェネリック型を設定に保存できないため、設定は別々の実行時間の間は保持されません。Settings.Designer.csを変更するのではなく、XML文字列を作成して設定に文字列として保存し、XMLからObservableCollection>をビルドします。その逆も同様です。

于 2012-09-29T23:13:38.757 に答える