さて、あなたのニーズに似た例を挙げてみましょう
このクラスを使用すると仮定しましょう:
public class MyObject
{
public int MyID;
public string MyString;
public ICommand MyCommand;
}
そしてDataGrid
、ID のリストを表示し、2 番目の列としてコンテンツとしてButton
プロパティを持つ a を表示します。これをクリックすると、必要に応じて新しいウィンドウで開く が起動します。MyString
ICommand
MyCommand
ビュー側に必要なものは次のとおりです。
<DataGrid ItemsSource="{Binding MyList}" AutoGenerateColumns="False">
<DataGrid.Columns>
<DataGridTextColumn Header="ID" Binding="{Binding MyID}" />
<DataGridTemplateColumn Header="Buttons">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Button Content="{Binding MyString}" Command="{Binding MyCommand}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
これにより、 「MyList」という名前のDataGrid
すべてのコンテンツが表示され、前に定義した 2 つの列が表示されます。IEnumerable<MyObject>
コマンドを定義する必要がある場合。まず、MVVM へのこの紹介リンクをRelayCommand
読んで、クラスを受講することをお勧めします (これは、問題に使用するものです)。
したがって、ViewModel
を定義するMyList
で、いくつかの便利なオブジェクトを定義する方法を次に示します。
public ObservableCollection<MyObject> MyList { get; set; }
// blah blah blah
public void InitializeMyList()
{
MyList = new ObservableCollection<MyObject>();
for (int i = 0; i < 5; i++)
{
MyList.Add(InitializeMyObject(i));
}
}
public MyObject InitializeMyObject(int i)
{
MyObject theObject = new MyObject();
theObject.MyID = i;
theObject.MyString = "The object " + i;
theObject.MyCommand = new RelayCommand(param =< this.ShowWindow(i));
return theObject
}
private void ShowWindow(int i)
{
// Just as an exammple, here I just show a MessageBox
MessageBox.Show("You clicked on object " + i + "!!!");
}
これは、必要なものを作成するのに十分なはずです。ご覧のとおり、everyは、新しいウィンドウを表示するように定義されButton
たメソッド ( ShowWindow
) を呼び出し、内部で必要なことを行います。はRelayCommand
、その名前が示すように、ボタンによって起動されたコマンドを実行ロジックを含むメソッドにリレーするために実際にここにあります。
そして... 必要なのはそれだけだと思います。返信が遅くなり申し訳ありません
編集 - 手動/動的に列を生成する
次のコードは、同様の問題が発生したときに実行しなければならなかったコードの一部です。ComboBox
私の問題は、 a が変更されるたびに表示される列を変更する必要があることでしたSelectedItem
。だから私はこれをSelectionChanged
イベントハンドラーに入れました。列を生成する必要がある正確な場所はわかりませんが、一般的な例を示します。
あなたItemsSource
がObservableCollection<MyNewObject>
MyNewObject
は次のとおりです。
public class MyNewObject
{
public IList<string> MyStrings { get; set; }
}
コードのどこかに(列を生成する必要がある場合に)次のコードを配置する必要がありますMyNewObject
。これは、リストの最初のものの長さに等しい数の列を生成します(注:これはコードビハインドにあり、DataGrid
あなたが取り組んでいるのはdataGridという名前です)
ObservableCollection<MyNewObject> source = dataGrid.ItemsSource as ObservableCollection<MyNewObject>;
if (source == null || source.Count == 0)
{
return;
}
MyNewObject firstObject = source[0];
for(int i = 0; i < firstObject.MyStrings.Count; i++)
{
// Creates one column filled with buttons for each string
DataGridTemplateColumn columnToAdd = new DataGridTemplateColumn();
columnToAdd.Width = 110; // I set a manual width, but you can do whatever you want
columnToAdd.Header = "Header number " + i;
// Create the template with a Button inside, bound to the appropriate string
DataTemplate dataTemplate = new DataTemplate(typeof(Button));
FrameworkElementFactory buttonElement = new FrameworkElementFactory(typeof(Button));
Binding binding = new Binding("MyStrings[" + i + "]");
binding.Mode = BindingMode.TwoWay;
binding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
buttonElement.SetBinding(Button.ContentProperty, binding);
// Do the same here for your command, or for whatever you want to do when the user clicks on this button
dataTemplate.VisualTree = buttonElement;
columnToAdd.CellTemplate = dataTemplate;
dataGrid.Columns.Add(columnToAdd);
}
これにより、最初のオブジェクトで見つかった文字列ごとに 1 つの列が作成されます。次に、必要なコマンドまたは表示トリックを使用して拡張します。