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

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

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

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

WPF

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

Q&A

解決済

1回答

1644閲覧

WPF Settings.settings コレクション保存

tomiieee

総合スコア27

C#

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

WPF

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

1グッド

0クリップ

投稿2020/08/29 00:54

編集2020/08/29 02:42

前提

C# WPF 初心者です。
用語の誤用/的外れな質問ありましたらご容赦ください。

表題/Memoを入力して、追加すると、下のリストボックスに内容が追加されるアプリを作成しています。
左側リストボックスを選択すると、右側のリストボックスに内容が表示される。
[イメージ説明]

実現したいこと

アプリ内で追加したリスト内容を保存し、アプリを再起動しても追加した内容が出てくるようにしたいです。
Settings.settingsを使用するのが一番楽かと思いますが、
リストボックスは、ソースコード内ではコレクションをバインドしています。
Settings.settingsにコレクションを追加することはできるのでしょうか?

該当のソースコード

C#

1using Prism.Mvvm; 2using System; 3using System.ComponentModel; 4using Reactive.Bindings; 5using System.Linq; 6using System.Reactive.Linq; 7using System.Collections.ObjectModel; 8 9namespace ListBoxデータ保存.ViewModels 10{ 11 public class MainWindowViewModel : BindableBase 12 { 13 public ReactiveProperty<string> Txt_Title { get; set; } = new ReactiveProperty<string>(); 14 public ReactiveProperty<string> Txt_Memo { get; set; } = new ReactiveProperty<string>(); 15 public ObservableCollection<Task> TaskList { get; set; } 16 17 18 //コマンド 19 public ReactiveCommand AddListCommand { get; private set; } 20 21 public MainWindowViewModel() 22 { 23 TaskList = new ObservableCollection<Task>(); 24 25 //コマンド生成 26 AddListCommand = Txt_Title 27 .Select(x => !string.IsNullOrEmpty(x)) 28 .ToReactiveCommand(); 29 30 //コマンド動作定義 31 AddListCommand.Subscribe(_ => 32 { 33 TaskList.Add(new Task { Title = Txt_Title.Value, Memo = Txt_Memo.Value }); 34 35 Txt_Title.Value = ""; 36 Txt_Memo.Value = ""; 37 }); 38 } 39 } 40 41 42 public class Task : BindableBase 43 { 44 public string Title { get; set; } 45 public string Memo { get; set; } 46 47 public ReactiveProperty<bool> IsSelected { get; set; } = new ReactiveProperty<bool>(); 48 } 49 50} 51

XAML

1<Window x:Class="ListBoxデータ保存.Views.MainWindow" 2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 4 xmlns:prism="http://prismlibrary.com/" 5 prism:ViewModelLocator.AutoWireViewModel="True" 6 Title="{Binding Title}" Height="350" Width="525" > 7 8 <Window.Resources> 9 <BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" /> 10 </Window.Resources> 11 12 <Grid> 13 <Grid.ColumnDefinitions> 14 <ColumnDefinition /> 15 <ColumnDefinition Width="2*" /> 16 </Grid.ColumnDefinitions> 17 <Grid.RowDefinitions> 18 <RowDefinition Height="Auto" /> 19 <RowDefinition /> 20 </Grid.RowDefinitions> 21 <Grid> 22 <Grid.ColumnDefinitions> 23 <ColumnDefinition Width="Auto" /> 24 <ColumnDefinition /> 25 </Grid.ColumnDefinitions> 26 <Label 27 Margin="5" 28 VerticalAlignment="Center" 29 Content="表題" HorizontalAlignment="Right" Width="34" /> 30 <TextBox 31 Grid.Column="1" 32 VerticalAlignment="Center" 33 Text="{Binding Txt_Title.Value, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" 34 TextWrapping="Wrap" Margin="10,0,10,0" /> 35 </Grid> 36 <Grid Grid.Column="1"> 37 <Grid.ColumnDefinitions> 38 <ColumnDefinition Width="Auto" /> 39 <ColumnDefinition /> 40 <ColumnDefinition Width="Auto" /> 41 </Grid.ColumnDefinitions> 42 <Label 43 Margin="5" 44 VerticalAlignment="Center" 45 Content="Memo" HorizontalAlignment="Right" Width="44" /> 46 <TextBox 47 Grid.Column="1" 48 Margin="5" 49 VerticalAlignment="Center" 50 Text="{Binding Txt_Memo.Value, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" 51 TextWrapping="Wrap" /> 52 <Button 53 Grid.Column="2" 54 MinWidth="56" 55 Margin="5" 56 Command="{Binding AddListCommand}" 57 Content="追加" HorizontalAlignment="Left" Width="56" /> 58 </Grid> 59 60 <Grid Grid.Row="1"> 61 <ListBox 62 x:Name="lst_Title" 63 Margin="5" 64 ItemsSource="{Binding TaskList}" 65 DisplayMemberPath="Title" 66 IsSynchronizedWithCurrentItem="True" 67 SelectionMode="Extended"> 68 69 <ListBox.ItemContainerStyle> 70 <Style TargetType="ListBoxItem"> 71 <Setter Property="IsSelected" Value="{Binding IsSelected.Value}" /> 72 </Style> 73 </ListBox.ItemContainerStyle> 74 </ListBox> 75 76 </Grid> 77 78 <Grid Grid.Row="1" Grid.Column="1" > 79 <ListBox 80 81 Margin="5" 82 ItemsSource="{Binding TaskList}"> 83 <ListBox.ItemContainerStyle> 84 <Style TargetType="ListBoxItem"> 85 <Setter Property="Visibility" Value="{Binding IsSelected.Value, Converter={StaticResource BooleanToVisibilityConverter}}" /> 86 </Style> 87 </ListBox.ItemContainerStyle> 88 <ListBox.ItemTemplate> 89 <DataTemplate> 90 <StackPanel> 91 <TextBlock FontWeight="Bold" Text="{Binding Title}" /> 92 <TextBlock Text="{Binding Memo}" /> 93 </StackPanel> 94 </DataTemplate> 95 </ListBox.ItemTemplate> 96 </ListBox> 97 </Grid> 98 99 </Grid> 100</Window> 101

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

OS:win10
.NET Framework:4.7.2
Visual Studio 2019

TN8001👍を押しています

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

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

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

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

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

退会済みユーザー

退会済みユーザー

2020/08/29 01:28 編集

開発環境(OS, .NET Framework, Visual Studio のバージョンなど)は書けませんか? 「Settingファイル」というのは Settings.settings のことですか? どのような形で格納したいのか具体的に書けませんか(コレクションとだけ言われても・・・ 前回の質問を読むというのも負担が大きすぎますし・・・)?
tomiieee

2020/08/29 02:44

情報不足申し訳ありません。 内容を修正いたしましたので、ご確認ください。
退会済みユーザー

退会済みユーザー

2020/08/29 02:50 編集

「どのような形で格納したいのか具体的に書けませんか」に対する回答がどこに書かれているのか分からないのですが・・・ 例えばですが、もしシリアライズして JSON 文字列にできるなら、それを Settings.settings に文字列として保存し、使うときは JSON 文字列 ⇒ オブジェクト(コレクション)にデシリアライスするというようなことは考えられないのでしょうか?
guest

回答1

0

ベストアンサー

Settings.Designer.csを編集すれば可能です。
が、Settings.settingsのデザイナをいじったりすると消えやすいので、別に書いたほうが安全です(partialなので)

TaskListMainWindowViewModel経由になっている深い意味はありません。

xml

1<Window 2 x:Class="Questions288214.Views.MainWindow" 3 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 4 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 5 xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" 6 xmlns:prism="http://prismlibrary.com/" 7 xmlns:properties="clr-namespace:Questions288214.Properties" 8 Width="{Binding Width, Mode=TwoWay, Source={x:Static properties:Settings.Default}}" 9 Height="{Binding Height, Mode=TwoWay, Source={x:Static properties:Settings.Default}}" 10 prism:ViewModelLocator.AutoWireViewModel="True" 11 Left="{Binding Left, Mode=TwoWay, Source={x:Static properties:Settings.Default}}" 12 Top="{Binding Top, Mode=TwoWay, Source={x:Static properties:Settings.Default}}"> 13 <Window.Resources> 14 <BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" /> 15 <Style TargetType="Label"> 16 <Setter Property="Margin" Value="5" /> 17 </Style> 18 <Style TargetType="TextBox"> 19 <Setter Property="Margin" Value="5" /> 20 <Setter Property="VerticalAlignment" Value="Center" /> 21 <Setter Property="TextWrapping" Value="Wrap" /> 22 </Style> 23 </Window.Resources> 24 <i:Interaction.Triggers> 25 <i:EventTrigger EventName="Closing"> 26 <prism:InvokeCommandAction Command="{Binding WindowClosingCommand}" /> 27 </i:EventTrigger> 28 </i:Interaction.Triggers> 29 <Grid> 30 <Grid.ColumnDefinitions> 31 <ColumnDefinition /> 32 <ColumnDefinition Width="2*" /> 33 </Grid.ColumnDefinitions> 34 <Grid.RowDefinitions> 35 <RowDefinition Height="Auto" /> 36 <RowDefinition /> 37 </Grid.RowDefinitions> 38 39 <Grid> 40 <Grid.ColumnDefinitions> 41 <ColumnDefinition Width="Auto" /> 42 <ColumnDefinition /> 43 </Grid.ColumnDefinitions> 44 <Label VerticalAlignment="Center" Content="表題" /> 45 <TextBox Grid.Column="1" Text="{Binding Txt_Title.Value, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" /> 46 </Grid> 47 48 <Grid Grid.Column="1"> 49 <Grid.ColumnDefinitions> 50 <ColumnDefinition Width="Auto" /> 51 <ColumnDefinition /> 52 <ColumnDefinition Width="Auto" /> 53 </Grid.ColumnDefinitions> 54 <Label VerticalAlignment="Center" Content="Memo" /> 55 <TextBox Grid.Column="1" Text="{Binding Txt_Memo.Value, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" /> 56 <Button 57 Grid.Column="2" 58 MinWidth="56" 59 Margin="5" 60 Command="{Binding AddListCommand}" 61 Content="追加" /> 62 </Grid> 63 64 <ListBox 65 x:Name="lst_Title" 66 Grid.Row="1" 67 Margin="5" 68 DisplayMemberPath="Title" 69 IsSynchronizedWithCurrentItem="True" 70 ItemsSource="{Binding TaskList}" 71 SelectionMode="Multiple"> 72 <ListBox.ItemContainerStyle> 73 <Style TargetType="ListBoxItem"> 74 <Setter Property="IsSelected" Value="{Binding IsSelected.Value}" /> 75 </Style> 76 </ListBox.ItemContainerStyle> 77 </ListBox> 78 79 <ListBox 80 Grid.Row="1" 81 Grid.Column="1" 82 Margin="5" 83 ItemsSource="{Binding TaskList}"> 84 <ListBox.ItemContainerStyle> 85 <Style TargetType="ListBoxItem"> 86 <Setter Property="Visibility" Value="{Binding IsSelected.Value, Converter={StaticResource BooleanToVisibilityConverter}}" /> 87 </Style> 88 </ListBox.ItemContainerStyle> 89 <ListBox.ItemTemplate> 90 <DataTemplate> 91 <StackPanel> 92 <TextBlock FontWeight="Bold" Text="{Binding Title}" /> 93 <TextBlock Text="{Binding Memo}" /> 94 </StackPanel> 95 </DataTemplate> 96 </ListBox.ItemTemplate> 97 </ListBox> 98 </Grid> 99</Window>

cs

1using System.Collections.ObjectModel; 2using System.Reactive.Linq; 3using Prism.Mvvm; 4using Reactive.Bindings; 5 6namespace Questions288214.ViewModels 7{ 8 public class MainWindowViewModel : BindableBase 9 { 10 public ReactiveProperty<string> Txt_Title { get; set; } = new ReactiveProperty<string>(); 11 public ReactiveProperty<string> Txt_Memo { get; set; } = new ReactiveProperty<string>(); 12 13 public ObservableCollection<Task> TaskList 14 { 15 get => Properties.Settings.Default.TaskList; 16 private set => Properties.Settings.Default.TaskList = value; 17 } 18 19 public ReactiveCommand AddListCommand { get; } 20 public ReactiveCommand WindowClosingCommand { get; } = new ReactiveCommand(); 21 22 23 public MainWindowViewModel() 24 { 25 if(TaskList == null) TaskList = new ObservableCollection<Task>(); 26 27 AddListCommand = Txt_Title 28 .Select(x => !string.IsNullOrEmpty(x)) 29 .ToReactiveCommand(); 30 31 AddListCommand.Subscribe(() => 32 { 33 TaskList.Add(new Task { Title = Txt_Title.Value, Memo = Txt_Memo.Value, }); 34 Txt_Title.Value = ""; 35 Txt_Memo.Value = ""; 36 }); 37 38 WindowClosingCommand.Subscribe(() => Properties.Settings.Default.Save()); 39 } 40 } 41 42 public class Task 43 { 44 public string Title { get; set; } 45 public string Memo { get; set; } 46 public ReactiveProperty<bool> IsSelected { get; set; } = new ReactiveProperty<bool>(); 47 } 48} 49 50// 別ファイルに書けば安心 51namespace Questions288214.Properties 52{ 53 using Questions288214.ViewModels; 54 55 internal sealed partial class Settings 56 { 57 [System.Configuration.UserScopedSetting()] 58 [System.Diagnostics.DebuggerNonUserCode()] 59 public ObservableCollection<Task> TaskList 60 { 61 get => (ObservableCollection<Task>)this[nameof(TaskList)]; 62 set => this[nameof(TaskList)] = value; 63 } 64 } 65}

ウィンドウ位置保存用は普通にデザイナで入れたとする

cs

1//------------------------------------------------------------------------------ 2// <auto-generated> 3// このコードはツールによって生成されました。 4// ランタイム バージョン:4.0.30319.42000 5// 6// このファイルへの変更は、以下の状況下で不正な動作の原因になったり、 7// コードが再生成されるときに損失したりします。 8// </auto-generated> 9//------------------------------------------------------------------------------ 10 11namespace Questions288214.Properties { 12 13 14 [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 15 [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "16.7.0.0")] 16 internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { 17 18 private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); 19 20 public static Settings Default { 21 get { 22 return defaultInstance; 23 } 24 } 25 26 [global::System.Configuration.UserScopedSettingAttribute()] 27 [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 28 [global::System.Configuration.DefaultSettingValueAttribute("NaN")] 29 public double Top { 30 get { 31 return ((double)(this["Top"])); 32 } 33 set { 34 this["Top"] = value; 35 } 36 } 37 38 [global::System.Configuration.UserScopedSettingAttribute()] 39 [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 40 [global::System.Configuration.DefaultSettingValueAttribute("NaN")] 41 public double Left { 42 get { 43 return ((double)(this["Left"])); 44 } 45 set { 46 this["Left"] = value; 47 } 48 } 49 50 [global::System.Configuration.UserScopedSettingAttribute()] 51 [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 52 [global::System.Configuration.DefaultSettingValueAttribute("525")] 53 public double Width { 54 get { 55 return ((double)(this["Width"])); 56 } 57 set { 58 this["Width"] = value; 59 } 60 } 61 62 [global::System.Configuration.UserScopedSettingAttribute()] 63 [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 64 [global::System.Configuration.DefaultSettingValueAttribute("350")] 65 public double Height { 66 get { 67 return ((double)(this["Height"])); 68 } 69 set { 70 this["Height"] = value; 71 } 72 } 73 } 74}

投稿2020/08/29 04:01

編集2023/07/23 04:58
TN8001

総合スコア9326

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

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

tomiieee

2020/08/29 23:17

解決できました。 ご回答ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問