【WPF】別ウィンドウに値を受け渡して、データを更新できるようにしてみた
おはようございます。
昨日に引き続き、
モーダル表示した子ウィンドウの話です。
こういった画面を作る際に必要となるのが、親画面から子画面(逆もまたしかり)へのデータ渡しですよね。
ということで、
今回はデータの修正を別ウィンドウで行うように修正するついでに、親から子へデータを渡す方法を試してみます。
プログラムは前回のものを。
https://www.doraxdora.com/blog/2017/08/18/post-2073/
スポンサーリンク
画面の変更
SubWindow.xaml
<Mah:MetroWindow x:Class="WpfApp1.SubWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApp1"
xmlns:Mah="clr-namespace:MahApps.Metro.Controls;assembly=MahApps.Metro"
mc:Ignorable="d"
Title="追加" Height="300" Width="300"
GlowBrush="{DynamicResource AccentColorBrush}"
Icon="/WpfApp1;component/Resource/Cat.ico"
BorderThickness="1"
WindowStartupLocation="CenterOwner"
>
<Window.Resources>
<ResourceDictionary Source="/Style/StyleDic.xaml"/>
</Window.Resources>
<Grid>
<Label Content="名前:" Margin="10,10,0,0" Style="{StaticResource lb-normal}" RenderTransformOrigin="0.522,0.893"/>
<TextBox x:Name="txt_name" Margin="61,12,0,0" HorizontalAlignment="Left" VerticalAlignment="Top" Width="100" Style="{StaticResource MetroTextBox}"/>
<Label Content="性別:" Margin="10,54,0,0" Style="{StaticResource lb-normal}"/>
<ComboBox x:Name="cmb_sex" HorizontalAlignment="Left" Margin="61,54,0,0" VerticalAlignment="Top" Width="50">
<ComboBoxItem Content="♂" HorizontalAlignment="Left" Width="50"/>
<ComboBoxItem Content="♀" HorizontalAlignment="Left" Width="50"/>
</ComboBox>
<ComboBox x:Name="cmb_kind" HorizontalAlignment="Left" Margin="61,140,0,0" VerticalAlignment="Top" Width="150"/>
<Label Content="年齢:" Margin="10,98,0,0" Style="{StaticResource lb-normal}"/>
<TextBox x:Name="txt_age" Margin="61,98,0,0" HorizontalAlignment="Left" VerticalAlignment="Top" Width="50" Style="{StaticResource MetroTextBox}"/>
<Label Content="種別:" Margin="10,143,0,0" Style="{StaticResource lb-normal}"/>
<Label Content="好物:" Margin="10,186,0,0" Style="{StaticResource lb-normal}"/>
<TextBox x:Name="txt_favorite" Margin="61,186,0,0" HorizontalAlignment="Left" VerticalAlignment="Top" Width="200" Style="{StaticResource MetroTextBox}"/>
<Button x:Name="btn_cansel" Content="キャンセル" HorizontalAlignment="Left" Margin="125,231,0,0" VerticalAlignment="Top" Width="75" Click="btn_cansel_Click"/>
<Button x:Name="btn_add" Content="追加" HorizontalAlignment="Left" Margin="205,231,0,0" VerticalAlignment="Top" Width="75" Click="btn_add_Click"/>
<Button x:Name="btn_mod" Content="更新" HorizontalAlignment="Left" Margin="205,231,0,0" VerticalAlignment="Top" Width="75" Click="btn_mod_Click" Visibility="Collapsed"/>
</Grid>
</Mah:MetroWindow>
プログラム修正
コンストラクタに引数を追加
親画面から値を受け取るために引数を追加します。
SubWindow.xaml.cs
public SubWindow()
を
public SubWindow(CatModel SelectedCat)
に変更する
グローバル変数の追加
更新時に参照するためにグローバルな変数に受け取ったデータを設定します。
SubWindow.xaml.cs
public CatModel SelectedCat { set; get; }初期化処理の修正
追加、更新でボタンの表示切替、及び画面へのデータ設定を行うようにします。
SubWindow.xaml.cs
public SubWindow(CatModel SelectedCat)
{
InitializeComponent();
// データを取得
// 種別マスタを取得してコンボボックスに設定する
using (var context = new PgDbContext())
{
var mstKind = context.Kinds;
IQueryable<Kind> result = from x in mstKind orderby x.KindCd select x;
var list = result.ToList();
// コンボボックスに設定
this.cmb_kind.ItemsSource = list;
this.cmb_kind.DisplayMemberPath = "KindName";
if (SelectedCat == null)
{
// 追加処理の場合
this.Title = "追加";
this.btn_add.Visibility = Visibility.Visible;
this.btn_mod.Visibility = Visibility.Collapsed;
}
else
{
this.SelectedCat = SelectedCat;
// 更新処理の場合
this.Title = "更新";
this.btn_add.Visibility = Visibility.Collapsed;
this.btn_mod.Visibility = Visibility.Visible;
// 値の設定
this.txt_name.Text = SelectedCat.Name;
foreach (ComboBoxItem i in this.cmb_sex.Items)
{
if (i.Content.ToString().Trim() == SelectedCat.Sex.Trim())
{
this.cmb_sex.SelectedItem = i;
}
}
this.txt_age.Text = SelectedCat.Age.ToString();
foreach (Kind k in list)
{
if (k.KindCd == SelectedCat.Kind)
{
this.cmb_kind.SelectedItem = k;
break;
}
}
this.txt_favorite.Text = SelectedCat.Favorite;
}
}
}
更新処理の追加
更新ボタンクリックイベントを追加します。
SubWindow.xaml.cs
/// <summary>
/// 更新ボタンクリックイベント.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btn_mod_Click(object sender, RoutedEventArgs e)
{
this.IsCancel = false;
// データを更新する
using (var context = new PgDbContext())
{
// 対象のテーブルオブジェクトを取得
var table = context.Cats;
// テーブルから対象のデータを取得
var target = table.Single(x => x.No == SelectedCat.No);
// データ変更
target.Name = this.txt_name.Text;
target.Sex = (this.cmb_sex.SelectedItem as ComboBoxItem).Content.ToString();
target.Age = int.Parse(this.txt_age.Text);
target.Kind = (this.cmb_kind.SelectedItem as Kind).KindCd;
target.Favorite = this.txt_favorite.Text;
// DBの変更を確定
context.SaveChanges();
MessageBox.Show("データを更新しました。");
}
this.Close();
}
追加ボタン押下処理の修正
SubWindowのコンストラクタに引数を追加したが、追加処理では特に子画面に渡すものがないので null を指定。
MainWindow.xaml.cs
/// <summary>
/// 追加ボタンクリックイベント
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void add_button_Click(object sender, RoutedEventArgs e)
{
logger.Info("追加ボタンクリック");
var win = new SubWindow(null);
win.Owner = GetWindow(this);
win.ShowDialog();
if (!win.IsCancel) {
// データ再検索
searchData();
}
}更新ボタン押下処理の修正
画面で選択されたデータを取得し子画面へ渡すように。
MainWindow.xaml.cs
/// <summary>
/// 更新ボタンクリックイベント
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void upd_button_Click(object sender, RoutedEventArgs e)
{
logger.Info("更新ボタンクリック");
// 選択チェック
if (this.dataGrid.SelectedItem == null)
{
MessageBox.Show("更新対象を選択してください。");
return;
}
// 選択されているデータを取得
CatModel cat = this.dataGrid.SelectedItem as CatModel;
var win = new SubWindow(cat);
win.Owner = GetWindow(this);
win.ShowDialog();
if (!win.IsCancel)
{
// データ再検索
searchData();
}
}
起動してみる
対象を選択して「更新」ボタンをクリックします。
別ウィンドウが表示され、選択されたデータが各項目に反映されています。
データを修正し、「更新」ボタンをクリックします。
確認メッセージが表示されます。
データが再検索され、更新が反映されていることが確認できました。
まとめ
無事に親画面から子画面へとデータを渡して処理することができました。
引数をオブジェクトの配列なんかにすると複数のパラメータを渡すことも可能ですね
という感じで、今回はここまでです。
ではでは。
ディスカッション
コメント一覧
初めまして。いつも参考にさせていただいています。
現在、こちらの記事のように一覧画面から追加ボタンをおしてサブウィンドウが開きDBに追加されるところまではできたのですが、親ウィンドウに戻ったときに、追加されたデータが表示されず困っています。
こちらの記事を参考にしているのですが私の知識不足で思うようにいきません。
もしよろしければ追加したデータの表示方法をご教授頂けないでしょうか?