廃版: Visual Studio / WPF > 実装 > 別のウィンドウのDataGridで入力した項目をもう一つのウィンドウのComboBox項目にする  > v0.1, v0.2

```txt:動作環境
Windows 7 Pro (32bit)
Microsoft Visual Studio 2017 Community
```

## 廃版
(追記 2017/07/02)

こちらの記事よりも以下の記事の方がBindingをよりよく使っているかもしれません。
http://qiita.com/7of9/items/80dd6a0fc9c924f7be6d


## 概要

- Personクラス 
- MainWindow
    - EditWindowを開く
    - ComboBoxを持つ
- EditWindow
    - DataGridを持つ

EditWindowで入力したDataGrid項目をMainWindowのComboBoxで表示したい。

## code v0.1

### Personクラス

```Person.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace _170612_t1810_datagrid_comboBox
{
    class Person
    {
        public bool Checked { get; set; }
        public string Name { get; set; }
        public string Race { get; set; }
    }
}
```

### MainWindow

```MainWindow.xaml.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
//
using System.Collections.ObjectModel;

namespace _170612_t1810_datagrid_comboBox
{
    /// <summary>
    /// MainWindow.xaml の相互作用ロジック
    /// </summary>
    public partial class MainWindow : Window
    {
        private EditWindow editWin;
        public MainWindow()
        {
            InitializeComponent();
        }

        private void updateComboBoxItems()
        {
            var dct = editWin.GetNames();
            var data = new List<MyComboBoxItem>();
            foreach (var elem in dct)
            {
                data.Add(new MyComboBoxItem { Name = elem });
            }
            uxNames.ItemsSource = data;
        }

        private void uxEdit_Click(object sender, RoutedEventArgs e)
        {
            if(editWin == null)
            {
                editWin = new EditWindow();
                editWin.Owner = this;
            }
            editWin.ShowDialog();
            updateComboBoxItems();
        }

        public class MyComboBoxItem
        {
            public string Name { get; set; }
        }       
    }
}
```

```MainWindow.xaml
<Window x:Class="_170612_t1810_datagrid_comboBox.MainWindow"
        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:_170612_t1810_datagrid_comboBox"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <ComboBox HorizontalAlignment="Left" Margin="29,28,0,0" 
                  VerticalAlignment="Top" Width="120"
                  x:Name="uxNames"                 
                  DisplayMemberPath="Name"
                  />
        <Button Content="Edit" 
                x:Name="uxEdit"
                Click="uxEdit_Click"
                HorizontalAlignment="Left" Margin="170,28,0,0" VerticalAlignment="Top" Width="75"/>
    </Grid>
</Window>
```

### EditWindow

```EditWindow.xaml.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
//
using System.IO;
using System.Globalization;
using System.Data;
using System.Collections.ObjectModel;

namespace _170612_t1810_datagrid_comboBox
{
    /// <summary>
    /// EditWindow.xaml の相互作用ロジック
    /// </summary>
    public partial class EditWindow : Window
    {
        private ObservableCollection<Person> myList;
        public EditWindow()
        {
            InitializeComponent();

            myList = new ObservableCollection<Person>();
            myList.Add(new Person { Checked = false, Name = "7of9", Race = "Borg" });
            myList.Add(new Person { Checked = false, Name = "Janeway", Race = "Human" });
            myList.Add(new Person { Checked = false, Name = "Neelix", Race = "Talaxian" });
            this.DataContext = myList;
        }

        public List<string> GetNames()
        {
            var data = new List<string>();
            foreach(var elem in myList)
            {
                data.Add(elem.Name);
            }
            return data;
        }

        private void uxAdd_Click(object sender, RoutedEventArgs e)
        {
            if(uxName.Text.Length == 0 || 
                uxRace.Text.Length == 0)
            {
                return;
            }
            var data = new Person
            {
                Checked = false,
                Name = uxName.Text,
                Race = uxRace.Text,
            };
            myList.Add(data);
        }

        private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
        {
            // 他のフォームから再度ShowModalしたときのエラーを回避するため
            e.Cancel = true;
            this.Visibility = Visibility.Hidden;
        }
    }
}
```

```EditWindow.xaml
<Window x:Class="_170612_t1810_datagrid_comboBox.EditWindow"
        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:_170612_t1810_datagrid_comboBox"
        mc:Ignorable="d"
        ResizeMode="NoResize"
        Title="EditWindow" Height="316.981" Width="448.113" Closing="Window_Closing">
    <Grid>
        <StackPanel>
            <StackPanel Orientation="Horizontal">
                <TextBlock Text="Name"/>
                <TextBox x:Name="uxName" Width="100"/>
                <TextBlock Text="Race"/>
                <TextBox x:Name="uxRace" Width="100"/>
                <Button x:Name="uxAdd" Content="Add" Click="uxAdd_Click" Width="100"/>
            </StackPanel>
            <DataGrid HorizontalAlignment="Left" Height="252" Margin="10,10,0,0" Width="406"
                      x:Name="uxDataGrid"
                      CanUserAddRows="False"
                      ItemsSource="{Binding}"/>
        </StackPanel>
    </Grid>
</Window>
```

### 結果

EditWindow(Tuvokを追加)
![2017-06-12_19h28_44.png](https://qiita-image-store.s3.amazonaws.com/0/32870/28483cb3-97c9-143c-3b2a-e60b3da282ca.png)

MainWindow(EditWindow閉じた後)
![2017-06-12_19h28_52.png](https://qiita-image-store.s3.amazonaws.com/0/32870/b0de95ce-06c8-60cd-e3c2-56ddaef16e9f.png)

## 備考

処理は希望通りだが、以下の問題がある。

### ComboBox項目の更新

- EditWindow.GetNames()を用意
- EditWindow.DataContextを渡したかった
    - でも失敗

以下の処理がだめな例。

```csharp
        private void updateComboBoxItems()
        {
            var dct = editWin.GetNames();
            var data = new List<MyComboBoxItem>();
            foreach (var elem in dct)
            {
                data.Add(new MyComboBoxItem { Name = elem });
            }
            uxNames.ItemsSource = data;
        }
```

Bindingでなんとかならないか。

### イベント処理

- DataGrid変更時は、イベント処理が良さそう

## code v0.2 > Binding使用

参考: https://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q1342704468

MainWindow.xamlに以下の変更をした。

- ItemsSourceを追加

```
        <ComboBox HorizontalAlignment="Left" Margin="29,28,0,0" 
                  VerticalAlignment="Top" Width="120"
                  x:Name="uxNames"                 
                  ItemsSource="{Binding}"
                  DisplayMemberPath="Name"
                  />

```

updateComboBoxItems()ではDataContextを設定するだけ。

```
        private void updateComboBoxItems()
        {
            uxNames.DataContext = editWin.DataContext;
        }
```

`public List<string> GetNames()`は不要になった。