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

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

新規登録して質問してみよう
ただいま回答率
85.48%
C#

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

WPF

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

Q&A

解決済

1回答

3336閲覧

【WPF】アプリ起動時にSettings.settingsに追加した設定値を読み込むと意図しない文字列が代入されてしまう原因を探りたい

toolscloudy

総合スコア20

C#

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

WPF

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

0グッド

0クリップ

投稿2019/10/09 15:32

前提・実現したいこと

開発環境 Visual Studio 2019
WPF .NetFramework 4.7.2

C#でユーザー任意の文字列を保存するために「Settings.settings」に「Indent」という名前のString変数を設定しています。(Properties.Settings.Defaultでアクセスできる変数です)

アプリの機能としてこの「Indent」という変数をユーザーがテキストボックスなどで任意に変更し、保存することができます。

問題となるのはここからで、アプリ起動時に「Indent」を読みだすと「\r\n 」という文字列に意図せず置き換わってしまっています。

下のソースでは「Indent」を「IndentChar」に代入して使っています。

該当のソースコード

アプリ起動時の読み出しとコンソール出力

C#

1 public class MainWindowModel : BindableBase 2 { 3 public MainWindowModel() 4 { 5 // ここで読みだされる 6 IndentChar = Properties.Settings.Default.Indent; 7 Console.WriteLine(Environment.NewLine + "Indent の中身:Start"); 8 Console.WriteLine("「" + IndentChar + "」"); 9 Console.WriteLine("Indent の中身:End" + Environment.NewLine); 10 11 CurrentFontFamily.Value = new FontFamily(Properties.Settings.Default.FontName); 12 CurrentFontSize.Value = Properties.Settings.Default.FontSize; 13 CurrentFontWeight.Value = FontWeight.FromOpenTypeWeight(Properties.Settings.Default.FontWeight); 14 CurrentHeaderLength = Properties.Settings.Default.HeaderLength; 15 TitleText.Value = nameof(Torimemo_i2); 16 IndentCharCount = Properties.Settings.Default.IndentCharCount; 17 } 18 }

コンソール出力

ユーザーによる設定値の変更(設定値が変更されるコードはここのみ)

C#

1 /// <summary> 2 /// タブ文字の変更 3 /// </summary> 4 private void TextBoxTextChanged_IndentChar(string text) 5 { 6 // ここでユーザー任意の文字列が代入される 7 Console.WriteLine(text); 8 Properties.Settings.Default.Indent = text; 9 MainWindowViewModel.IndentChar = text; 10 }

アプリ終了時に保存

C#

1 /// <summary> 2 /// 終了処理 3 /// </summary> 4 private void ConfigWindow_Closing() 5 { 6 // アプリを閉じると保存 7 Properties.Settings.Default.Save(); 8 }

試したこと

  1. Settings.settingsを新たに作り直す
  2. Visual Studioの再起動・ソリューション、アプリのリビルド

補足情報(FW/ツールのバージョンなど)

補足ですが、アプリを起動して「Indent」の値を変更して保存すると、アプリを起動中の間はちゃんと代入された値を使用できます。また「Indent」の他にも「文字フォント(FontFamily)」などの設定値はあるのですが、そちらは問題なく保存され、アプリを再起動しても意図した値を読み取ることができます。

聞いても……な気はするのですが、このような現象に心当たりのある方がいれば意見をお聞きしたいです。

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

dodox86

2019/10/09 18:10

コンストラクタで使用しているということで、起動直後にSettingsがロードされるタイミングの問題かなと思いましたが、再現しませんでした。(.NETのバージョンなどは違います) Properties.Settings.Default.Save()したときは、実際にどのような文字列シーケンスになっていますか?何かしらの空白文字('\t'など)でしょうか。settingsの保存先のファイルはXMLなので、空白文字のエンコードと、アプリ起動時のXMLからのデコード時に想定していない形で復元されているのかもしれません。SettingsのXMLファイルを確認してみてください。
toolscloudy

2019/10/10 00:54

「Properties.Settings.Default.Indent(以下、Indent)」 に格納される値は、半角スペース・全角スペース・タブ文字などを想定しています。 言われてみればと思い、SettingsのXMLファイルを確認するため以下を試行しました。 保存前後の値の確認です。 、、、 1.Indentに半角スペースを代入※1 2.設定を保存(Properties.Settings.Default.Sava()) 3.XMLファイルに「\r\n 」が保存された(正確には下記の「保存後」) ※1 全角スペース・タブ文字も同様に試しています。 「保存前」のXMLファイルの内容(抜粋) <setting name="Indent" serializeAs="String"> <value /> </setting> 「保存後」のXMLファイルの内容(抜粋) <setting name="Indent" serializeAs="String"> <value> </value> </setting> 「Indent」に ”A” という文字を代入して保存した場合。 <setting name="Indent" serializeAs="String"> <value>A</value> </setting> 、、、 IndentにAを代入した場合はその値を読み込むことができました。そのため、読み込んだ時というよりは、保存するときに何らかの原因があるように思えます。文字コードの問題なのでしょうか……。 以下、過程です。 1.「Appdata/Local/アプリ名フォルダ」内にあるuser.config(以下、XML)を削除 2.ビルド後に、アプリを起動。 3.Indentの設定値を変えずに、保存し、アプリを終了。この時のXMLは上記の「保存前」。 4.アプリを起動し、Indentの設定値を半角スペースに変えて(アプリの機能で変更後)保存し、アプリを終了。この時のXMLは上記の「保存後」。 5.再度起動し、Indentを読み取ると「\r\n 」の文字列シーケンスが代入されている。Indentの設定値をAに変えて保存し、終了。 7.起動し、Indentを見るとAを読み取れる。
dodox86

2019/10/10 01:29

文字コードもあるかもしれませんが、*.config は結局XMLなので、XMLのルールと内部で使っている.NET Frameworkの影響かもしれません。XMLでは値中の空白文字の扱いが一部、特殊です。
toolscloudy

2019/10/10 02:02

結局、私にはよくわかりませんでした。せっかく、ご回答いただいたのに申し訳ありませんが、解決策ではなく回避策としてZuishinさんの意見を採用しようと思います。 回答ありがとうございました。
dodox86

2019/10/10 02:10

> 回避策としてZuishinさんの意見を採用しようと思います。 今、確実に動く簡単な方法で対応されるのが良いと私も思います。承知しました。
guest

回答1

0

ベストアンサー

TextBoxTextChanged_IndentChar はデータバインディングでもなく、イベントハンドラでもありません。ここにブレークポイントを置き、いつ呼び出されているかチェックしてください。終了時に呼び出されていると思います。

投稿2019/10/09 22:58

Zuishin

総合スコア28660

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Zuishin

2019/10/09 23:02

または app.config を常にコピーしているのかもしれません。起動時ではなくビルド時にクリアされていないか確かめてください。
toolscloudy

2019/10/10 01:33

#1 「TextBoxTextChanged_IndentChar」は、ReactivePropertyというライブラリのReactivePropertyを用いて、TextBoxのTextプロパティにバインドさせています。 、、、 // 宣言部 public ReactiveProperty<string> IndentChar { get; } = new ReactiveProperty<string>(); IndentChar.Subscribe(TextBoxTextChanged_IndentChar); 、、、 、、、 // XAML <TextBox Text="{Binding IndentChar.Value,UpdateSourceTrigger=PropertyChanged}" assist:TextBoxAssist.Watermark="タブ文字" AcceptsTab="True"/> 、、、 また、「TextBoxTextChanged_IndentChar」にブレークポイントを置き、いつ呼び出されているかを確認しましたが、終了時には呼び出されていませんでした。 #2 app.configを常にコピーというのはVisual Studioのソリューションエクスプローラーからプロパティを見た際の「出力ディレクトリにコピー」という項目のことを指しているのでしょうか? それでしたら、「コピーしない」となっています。それ以外に何らかの要因を示唆しているのでしたら、申し訳ありませんが、ご教授下さると幸いです。 それと、起動時にではなくビルド時にクリアされていないか確認というのは、つまりどういったことでしょうか? それも教えて下さると助かります……。
Zuishin

2019/10/10 01:44

ビルド時にコピーされているのかと思いましたが、違いましたね。XML の問題だとしたら、生のコードを直接保存するのではなく、保存する際にエンコード、読み取る際にデコードすれば改善すると思います。そのような処理をしなければならないというのが不可解ですが。エンコードはたとえば半角スペース四つを ssss に変えるなど簡単な置換で十分だと思います。
toolscloudy

2019/10/10 01:59

設定管理をINIファイルにしてしまおうかとも思ったのですが、Zuishinさんの意見を採用しようと思います。 正直、正常に動作していた時期があるので不思議に思います(そう思っていただけかもしれないですが)。 回答ありがとうございました。
Zuishin

2019/10/10 02:07

私が今確かめられないので何とも言えませんが、正常に動きそうな気はするんですよね。よくわかりませんが、.NET Core 3.0 を入れたら私のところでも不可解なことが起きるようになったので、一時的なものかも知れません。
dodox86

2019/10/10 02:08

> 正直、正常に動作していた時期があるので不思議に思います(そう思っていただけかもしれないですが)。 Visual Studio や.NET Frameworkのバージョンの差異ではないでしょうか。新しく迷い込んだバグか、むしろ今の動きが正当か。。。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問