質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.84%

  • C#

    6255questions

    C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

  • Visual Studio

    1616questions

    Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

  • WPF

    638questions

    Windows Presentation Foundation (WPF) は、魅力的な外観のユーザー エクスペリエンスを持つ Windows クライアント アプリケーションを作成するための次世代プレゼンテーション システムです

Visual Studioで独自クラスを設定に保存する方法が分かりません。C# WPF

解決済

回答 3

投稿

  • 評価
  • クリップ 0
  • VIEW 225

gucha

score 32

ソフトの設定などをSettings.settingsで作った設定を利用して読み書きするところまではできたのですが、種類に自作したクラスを設定する方法が分かりません。

イメージ説明

こちらで紹介されているように設定したつもりなのですが[種類]には作成したクラスが表示されません。
https://dobon.net/vb/dotnet/programing/mysettings.html#section5

試したことは
確認用のプロジェクトを新規作成後、Settings.csに紹介されているコードを追加しただけです。[種類]に追加したLinesが追加されることを期待していたのですが新たに追加されたものはありませんでした。

namespace testApp.Properties {    

    // このクラスでは設定クラスでの特定のイベントを処理することができます:
    //  SettingChanging イベントは、設定値が変更される前に発生します。
    //  PropertyChanged イベントは、設定値が変更された後に発生します。
    //  SettingsLoaded イベントは、設定値が読み込まれた後に発生します。
    //  SettingsSaving イベントは、設定値が保存される前に発生します。
    internal sealed partial class Settings {

        [global::System.Configuration.UserScopedSettingAttribute()]
        public System.Collections.Generic.List<string> Lines
        {
            get
            {
                return ((System.Collections.Generic.List<string>)(this["Lines"]));
            }
            set
            {
                this["Lines"] = value;
            }
        }

        public Settings() {

            // // 設定の保存と変更のイベント ハンドラーを追加するには、以下の行のコメントを解除します:
            //
            // this.SettingChanging += this.SettingChangingEventHandler;
            //
            // this.SettingsSaving += this.SettingsSavingEventHandler;
            //
        }

        private void SettingChangingEventHandler(object sender, System.Configuration.SettingChangingEventArgs e) {
            // SettingChangingEvent イベントを処理するコードをここに追加してください。
        }

        private void SettingsSavingEventHandler(object sender, System.ComponentModel.CancelEventArgs e) {
            // SettingsSaving イベントを処理するコードをここに追加してください。
        }
    }
}

Visual Studio 2017でWPFアプリです。
やり方が間違えているのでしょうか?それとも元から期待している内容が実現不可能なのでしょうか?

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 3

checkベストアンサー

+1

こんにちは。

Setting.cs ではなく、 Settings.Designer.cs に同様の内容を書いてください。
それによって

Properties.Settings.Default.Lines


でアクセスできるようになります。デザイナから設定値をセットできませんから、プログラムで一旦書き込んでおく必要があります。

なお、プロジェクトのプロパティ -> 設定 の画面にはLinesは表示されません。
また、独自のクラスを種類に表示することについては質問者様が示したリンク先にも記載されていません。あくまで独自のクラスを使うことができると言っているだけです。

もし質問の本意が、独自クラスを種類の選択肢に表示させてデザイナから設定値を操作したい、ということであればこの回答は適さないです。申し訳ありません。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/06/10 00:22

    皆様から教えて頂いた方法を確認して今回は「元から期待している内容が実現不可能」だったということが理解できました。
    partial class Settingsに独自クラスを追加しておくという方法が一番簡単に操作できると思ったのでこちらの回答をベストアンサーとさせていただきます。
    次回以降は質問の「目的」をはっきりとさせてから質問するようにします。
    皆様ありがとうございました。

    キャンセル

+1

こちらの方法は、設定の画面の「種類」を増やす方法ではありません。
Properties.Settings.Default.LinesとList<string>の項目を
追加するコードになります。
要は、デザイナを使用せずに、コードで設定項目を増やしている行為となります。

デザイナ上の「種類」を追加する方法に関しては、私もわかりません。

 追記

DLLを作成しての方法ですが、以下のようにしたところ、設定のデザイナ上でも設定でき、プログラム上からも
値の保存ができました。

DLL側

using System;
using System.ComponentModel;
using System.Globalization;

namespace TestDLL
{
    [TypeConverter(typeof(CustomClassConverter))]
    public class TestClass1
    {
        public int Test { get; set; }
        public string Test2 { get; set; }
    }

    public class CustomClassConverter : ExpandableObjectConverter
    {
        //コンバータがオブジェクトを指定した型に変換できるか
        //(変換できる時はTrueを返す)
        public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
        {
            if (destinationType == typeof(TestClass1))
                return true;
            return base.CanConvertTo(context, destinationType);
        }

        //指定した値オブジェクトを、指定した型に変換する
        public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
        {
            if (destinationType == typeof(string) && value is TestClass1)
            {
                TestClass1 cc = (TestClass1)value;
                return cc.Test.ToString() + "," + cc.Test2;
            }
            return base.ConvertTo(context, culture, value, destinationType);
        }

        //コンバータが特定の型のオブジェクトをコンバータの型に変換できるか
        //(変換できる時はTrueを返す)
        //ここでは、String型のオブジェクトなら変換可能とする
        public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
        {
            if (sourceType == typeof(string))
                return true;
            return base.CanConvertFrom(context, sourceType);
        }

        //指定した値をコンバータの型に変換する
        public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
        {
            if (value is string)
            {
                string[] c = value.ToString().Split(new char[]{','},2);
                TestClass1 cc = new TestClass1();
                cc.Test = int.Parse(c[0]);
                cc.Test2 = c[1];

                return cc;
            }
            return base.ConvertFrom(context, culture, value);
        }
    }
}

下図のようにデザイナ上で設定でき
イメージ説明

保存結果はこうなりました。

    <userSettings>
        <WindowsFormsApp1.Properties.Settings>
            <setting name="Test" serializeAs="String">
                <value>123,ABC</value>
            </setting>
        </WindowsFormsApp1.Properties.Settings>
    </userSettings>

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

+1

[種類]のドロップダウンリストの一番下に[参照…]が出てませんか?
そこから辿れば選択できると思います。
--- 追記 ---
とりあえずXMLにシリアライズ-デシリアライズする方法はありました。
参照…でMyItemTypeを指定して値にXMLの部分を入れてみてください。

namespace ClassLibrary1
{
    [XmlRoot("myItemType")]
    public class MyItemType
    {
        [XmlElement("name")]
        public string Name { get; set; }
    }
}
<?xml version="1.0" encoding="utf-16"?>
<myItemType xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <name>hoge</name>
</myItemType>

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/06/08 19:59

    参照から辿りましたが見つかりませんでした。環境の差でしょうか・・・。

    キャンセル

  • 2018/06/08 21:05

    私も確認のため探ったのですがList型は見当たりませんでした。(stringのコレクションクラスはありました)
    オリジナルのクラスを定義すると見えるかもと思ってやってみましたが、それも追加されないようでした。
    私の環境はVS2017です。

    キャンセル

  • 2018/06/09 10:48

    こちらもVS2017です。
    既存のソリューションの場合は[参照…]から辿れますが、新規でプロジェクトを作ったら名前空間すら出てきませんね。
    コンパイルやVSの再起動をしただけでは出ないみたいです。
    時間があるときに探ってみます。

    キャンセル

  • 2018/06/09 11:20

    自作DLLにTestClassを作成し、そのDLLを参照した場合に[参照]からTestClassを追加することができました。
    ただ、
    public class TestClass1
    {
    private int _Test;
    public int Test {
    get { return _Test; }
    set { _Test = value; }
    }

    }
    としか書いてないので、デザインから値の設定はできません。
    多分、TypeConverter等の実装が必要なのかと思います。

    キャンセル

  • 2018/06/09 13:13

    XMLにシリアライズ-デシリアライズする方法を追記しました。

    キャンセル

  • 2018/06/10 00:09

    YAmaGNZさん
    クラスを作るごとにDLLを調整するのは手間がありそうですがこちらの方法があることも知れて良かったです。教えて頂きありがとうございました。
     
    hihijijiさん
    こちらも別の方法で教えて頂きありがとうございます。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.84%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • C#

    6255questions

    C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

  • Visual Studio

    1616questions

    Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

  • WPF

    638questions

    Windows Presentation Foundation (WPF) は、魅力的な外観のユーザー エクスペリエンスを持つ Windows クライアント アプリケーションを作成するための次世代プレゼンテーション システムです