C# と VB.NET の質問掲示板

わんくま同盟

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

ツリー一括表示

C# WPFで、親子両方で共通で使うデータを作りたい /おきみどり (23/09/26(Tue) 10:53) #102422
Re[1]: C# WPFで、親子両方で共通で使うデータを作りたい /radian (23/09/27(Wed) 10:41) #102423


親記事 / ▼[ 102423 ]
■102422 / 親階層)  C# WPFで、親子両方で共通で使うデータを作りたい
□投稿者/ おきみどり (1回)-(2023/09/26(Tue) 10:53:44)

分類:[.NET 全般] 

WPF C# .NET 6.0

親子間で共通で使うデータを作りたいと思っています。
子側にDataGridを用意し、親側にはそれに見合ったものを表示させたり編集させたりする予定です。
子側で選択したものに応じてボタン動的生成および選択も検討しています。

データとしては、とりあえず必要なものとして以下4つを利用します。
ID(固有)
タイトル
画像ファイル名(ファイルパス)
画像サイズ(X,Y,Width,Height)

やりたい事としては、
・共通で利用できるデータにすること
 ViewModelなど

・DataGridで選択している行の値を常に取得でき、親側でも何を選択しているか分かる事
 →現在選択しているDataGridの行の値が知りたい、選択行が変わったら更新したい。
  また、親で子に関係あるものをクリックした際、自動でDataGridの選択も変えたい。(連動したい)

・DataGridのデータは、CSV書き出し読み込みが出来ること
 

です。

ViewModelで共有を考えてみたのですが、MVVM等良く分からず、断念してしまいました。

WPF C# 親ウィンドウと子ウィンドウのデータ共有
https://teratail.com/questions/jru5bj6b9xz7g1

上記が参考になるかと思ってみていたのですが
SubWindw側でCSVファイルを読んでデータを入れたり編集したい場合は
どのようにしたら良いのでしょう?

--ViewModel--

    public class ViewModel
    {
        public ObservableCollection<Item> Items { get; } = new ObservableCollection<Item>();
        public ICommand DelCommand { get; }

        public ViewModel()
        {

        }

    }


    public class Item : ObservableObject // INotifyPropertyChanged
    {
        public int Num { get => _Num; set => SetProperty(ref _Num, value); }
        private int _Num;
        public string Title { get => _Title; set => SetProperty(ref _Title, value); }
        private string _Title;
        public string PicName { get => _PicName; set => SetProperty(ref _PicName, value); }
        private string _PicName;
        public int X { get => _X; set => SetProperty(ref _X, value); }
        private int _X;
        public int Y { get => _Y; set => SetProperty(ref _Y, value); }
        private int _Y;
        public int Width { get => _Width; set => SetProperty(ref _Width, value); }
        private int _Width;
        public int Height { get => _Height; set => SetProperty(ref _Height, value); }
        private int _Height;
    }

-------------
Sub
    <DockPanel>
        <ToolBar Height="30" DockPanel.Dock="Top" FontWeight="Bold" >
                <Button x:Name="ReadFileB" Content="ファイル読み込み" Click="ReadFile_Click" Background="#FFFFBCDE" />
                <Button x:Name="WriteFileB" Content="ファイル書き込み" Click="WriteFile_Click" Background="#FFAFFFD5" />
            </ToolBar>
            <!--<rg:ReoGridControl x:Name = "ReoGrid" Height="300"  />-->
        <DataGrid x:Name="DataGrid" IsReadOnly="True"  ItemsSource="{Binding Items}" CanUserSortColumns="False" SelectionChanged="DataGrid_SelectionChanged" AutoGenerateColumns="False" CanUserReorderColumns="False" >
            <DataGrid.Columns>
                <DataGridTextColumn Header="番号" Binding="{Binding Num}"  />
                <DataGridTextColumn Header="タイトル" Binding="{Binding Title}"  />
                <DataGridTextColumn Header="画像ファイル名" Binding="{Binding PicName}"/>
                <DataGridTextColumn Header="X" Binding="{Binding X}"  />
                <DataGridTextColumn Header="Y" Binding="{Binding Y}"  />
                <DataGridTextColumn Header="W" Binding="{Binding Width}"  />
                <DataGridTextColumn Header="H" Binding="{Binding Height}"  />
                <DataGridTemplateColumn Header="追加" x:Name="Add">
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <Button Click="Add_Click" Content="+" />
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                </DataGridTemplateColumn>
                <DataGridTemplateColumn Header="削除">
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <Button
                            Command="{Binding DataContext.DelCommand, Source={x:Reference Root}}"
                            CommandParameter="{Binding}"
                            Content="-" /> 
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                </DataGridTemplateColumn>
            </DataGrid.Columns>
        </DataGrid>
    </DockPanel>
----------------
//書き込み読み込み※なにか違う……
        /*ファイル読み込み*/
        ObservableCollection<MyData> ReadFile(string filepath)
        {
   System.Text.Encoding.RegisterProvider(System.Text.CodePagesEncodingProvider.Instance); // memo: Shift-JISを扱うためのおまじない
   // ダイアログのインスタンスを生成
   var dialog = new OpenFileDialog();

   // ファイルの種類を設定
   dialog.Filter = "CSV (*.csv)|*.csv";
   dialog.InitialDirectory = System.AppDomain.CurrentDomain.BaseDirectory.TrimEnd('\\');//今のパス
   // ダイアログを表示する
   if (dialog.ShowDialog() == true)
   {
       // 選択されたファイル名 (ファイルパス) をメッセージボックスに表示
       // ファイルを読み取り形式で開く
       Encoding sjisEnc = Encoding.GetEncoding("Shift_JIS");
       StreamReader file = new StreamReader(dialog.FileName, sjisEnc);
       string line = null;
       while ((line = file.ReadLine()) != null)    // 1行ずつ読み込む
       {
           string[] tango = line.Split(',');       // カンマで区切って配列に格納
           var ret = int.TryParse(tango[0], out _);
           if (ret == false)
           {
               MessageBox.Show("読み込むCSVが違うようです");
               return null;
           }
           var d1 = int.Parse(tango[0]);//id
           var d2 = tango[1];//Title
           var d3 = tango[2];//PicName
           var d4 = int.Parse(tango[3]);//X
           var d5 = int.Parse(tango[4]);//Y
           var d6 = int.Parse(tango[5]);//Width
           var d7 = int.Parse(tango[6]);//Height
           var d8 = tango[7];//HintText
           var d9 = tango[8];//HintText
           var d10 = tango[9];//HintText
           mydata.Add(new MyData(d1, d2, d3, d4, d5, d6, d7, d8, d9, d10));
       }
       file.Close();
   }
   else
   {
       Console.WriteLine("CSVファイルを読み込めませんでした");       // エラーメッセージを表示
   }

   return mydata;
        }

        /*ファイル書き込み*/
        public void ExportCSV()
        {
   Microsoft.Win32.SaveFileDialog dlg = new Microsoft.Win32.SaveFileDialog();
   dlg.InitialDirectory = System.AppDomain.CurrentDomain.BaseDirectory.TrimEnd('\\');//今のパス
   //保存先の初期値(マイドキュメント)
   dlg.InitialDirectory = System.Environment.GetFolderPath(Environment.SpecialFolder.Personal);
   dlg.Title = "保存先のファイルを選択してください";
   dlg.Filter = "CSVファイル(*.csv)|*.csv";
   if (dlg.ShowDialog() == true)
   {
       try
       {
           using (var sw = new System.IO.StreamWriter(dlg.FileName, false, System.Text.Encoding.GetEncoding("UTF-8")))
           {
               foreach (MyData d in mydata)
               {
           sw.WriteLine(dqot(d.Name) + "," + dqot(d.Place));
                   var lineData = d.Num + "," + d.Title + "," + d.PicName + "," +
                       d.X + "," + d.Y + "," + d.Width + "," + d.Height + "," + d.HintText + "," +
                       d.BorderColor + "," + d.FillColor;
                   sw.WriteLine(lineData);
               }
           }
           MessageBox.Show("保存しました");
       }
       catch (SystemException ex)
       {
           System.Console.WriteLine(ex.Message);

       }
   }
        }


[ □ Tree ] 返信 編集キー/

▲[ 102422 ] / 返信無し
■102423 / 1階層)  Re[1]: C# WPFで、親子両方で共通で使うデータを作りたい
□投稿者/ radian (151回)-(2023/09/27(Wed) 10:41:39)
2023/09/27(Wed) 10:54:53 編集(投稿者)

No102422 (おきみどり さん) に返信
> ViewModelで共有を考えてみたのですが、MVVM等良く分からず、断念してしまいました。
>
> WPF C# 親ウィンドウと子ウィンドウのデータ共有
> https://teratail.com/questions/jru5bj6b9xz7g1
>
> 上記が参考になるかと思ってみていたのですが
> SubWindw側でCSVファイルを読んでデータを入れたり編集したい場合は
> どのようにしたら良いのでしょう?

質問者さんのスキルが分からないので回答しづらいですが、
とりあえずMVVMという話を横においておくと、
データ共有するのであれば、データ受け渡し用のクラスを作って、それを子画面を作るときにコンストラクタかプロパティ経由で渡せば、親子でデータの共有は出来ると思います。
リンク先では、子画面を作って表示する時に、子のDataContextに親側のViewModelを渡して、ViewModelを共有していますね。

MVVM自体がよく分からない、となると、まずMVVMを勉強するしかないと思います。
それはボリュームが大きすぎるので、掲示板で回答出来る範疇を超えています。
[ 親 102422 / □ Tree ] 返信 編集キー/


管理者用

- Child Tree -