2016-05-22 4 views
-1

まあ、私のlast questionはダウンボトム以外の応答を得られませんでしたので、質問を分解して一度に一つの基本的な質問をします。WPFのグリッドにローとコントロールを宣言的に追加

私はグリッド(DataGridではない)があるWPFアプリケーションを持っています。今は実行時に行を追加したいと思います。これらの行のそれぞれには、TextBoxやComboboxのようなコントロールがあります。私はRowDefinitions.Add(New RowDefinition())でこれを行うことができ、WinFormsのTableLayoutPanelで行ったように、行の各セルに個々のコントロールを追加することができると私は理解しています。しかし、ボタンをクリックするかイベントがトリガされたときに、イベントハンドラを持つすべてのコントロールがグリッドの新しい行のそれぞれのセルに追加されるもっと洗練されたソリューションを探していました。それを行う簡単な方法はありますか?

P.S.それがここの要素であれば、必要に応じて行を削除する必要もあります。削除された行が必ずしも最後の行であるとは限りません。

+0

私はこれまで何度も何度も説明しました。 StackOverflowで "WPF ItemsControl MVVM"を検索してください。 –

+0

私は前に答えた質問の1つであなたの解決策を見ましたが、理解するのは難しかったです。私は完全にWPFに慣れていて、MVVMについて全く考えていません。あなたがMVVMとWPFの基礎を学ぶ良い本の方に私を親切に指してもらえれば幸いです。私はすでにレイチェルのブログを訪れていますが、それは私にはあまり意味がありません。 –

+0

主な考え方は、WPFでコードを使用してUI要素を作成または操作しないことです。その代わりに、表示するデータを含むクラスを作成し、そのクラスのコレクションを作成し、WPFのデータバインディング機能を使用してUIをデータに「リンク」して、UIの状態がデータは常にあります。 –

答えて

0

通常、DataGridを使用して、グリッドが ではなく、繰り返しのある行でデータを表示する方がよいでしょう。しかし、グリッドを使用する特別な理由がある場合は、グリッドを使用してコードサンプルを添付し、各行にテキストボックス、コンボボックス、およびDeleteButtonを表示しています。 [Add]ボタンを使用すると、下に新しい行を追加できます。すべての行のDeleteButtonを使用すると、その行を削除できます。

XAML:

<Window x:Class="GridAddRow.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:GridAddRow" 
     mc:Ignorable="d" 
     Title="MainWindow" Height="350" Width="525"> 
    <DockPanel> 
    <Grid Name="MainGrid" DockPanel.Dock="Top"/> 
    <Button DockPanel.Dock="Top" Name="AddButton" Content="Add"/> 
    <Rectangle Fill="Gainsboro"/> 
    </DockPanel> 
</Window> 

C#の:基本的にはちょうどあなたがすべてのコントロールのための一つの特性を持つクラスを作成する必要があることを意味し、 "あなたはMVVMを使用する必要があります" と言っ

using System.Collections.Generic; 
using System.Windows; 
using System.Windows.Controls; 

namespace GridAddRow { 

    public partial class MainWindow: Window { 

    int textCol, comboBoxCol, buttonCol; 

    public MainWindow() { 
     InitializeComponent(); 

     //initialise MainGrid, i.e. define columns, could be done in XAML 
     addCol(out textCol, new GridLength(100)); 
     addCol(out comboBoxCol, GridLength.Auto); 
     addCol(out buttonCol, GridLength.Auto); 

     //initialise grid content, usually read from a db 
     addRow("Some Text", 1); 
     addRow("Another String", 3); 

     AddButton.Click += AddButton_Click; 
    } 

    private void addCol(out int textCol, GridLength gridLength) { 
     textCol = MainGrid.ColumnDefinitions.Count; 
     MainGrid.ColumnDefinitions.Add(new ColumnDefinition { Width = gridLength }); 
    } 

    List<TextBox> textBoxes = new List<TextBox>(); 
    List<ComboBox> comboBoxes = new List<ComboBox>(); 

    private void addRow(string textBoxString, int comboBoxIndex) { 
     int rowId = MainGrid.RowDefinitions.Count; 
     MainGrid.RowDefinitions.Add(new RowDefinition()); 

     TextBox textBox = new TextBox { Text = textBoxString }; 
     textBoxes.Add(textBox); 
     addControl(textBox, rowId, textCol); 
     textBox.TextChanged += TextBox_TextChanged; 

     ComboBox comboBox = new ComboBox {SelectedIndex= comboBoxIndex }; 
     comboBox.Items.Add(new ComboBoxItem {Content="0" }); 
     comboBox.Items.Add(new ComboBoxItem { Content="1" }); 
     comboBox.Items.Add(new ComboBoxItem { Content="2" }); 
     comboBox.Items.Add(new ComboBoxItem { Content="3" }); 
     comboBoxes.Add(comboBox); 
     addControl(comboBox, rowId, comboBoxCol); 
     comboBox.SelectionChanged += ComboBox_SelectionChanged; 

     Button deleteRowButton = new Button {Content = "Delete"}; 
     addControl(deleteRowButton, rowId, buttonCol); 
     deleteRowButton.Click += DeleteRowButton_Click; 
    } 

    private void addControl(Control control, int rowId, int textCol) { 
     control.Tag = rowId; 
     MainGrid.Children.Add(control); 
     Grid.SetRow(control, rowId); 
     Grid.SetColumn(control, textCol); 
    } 

    private void TextBox_TextChanged(object sender, TextChangedEventArgs e) { 
     TextBox textbox = (TextBox)sender; 
     int rowid = (int)textbox.Tag; 
     //do something here. 
    } 

    private void ComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e) { 
     ComboBox comboBox = (ComboBox)sender; 
     int rowid = (int)comboBox.Tag; 
     //do something here. 
    } 

    private void DeleteRowButton_Click(object sender, RoutedEventArgs e) { 
     Button deleteButton = (Button)sender; 
     int rowid = (int)deleteButton.Tag; 
     MainGrid.Children.Remove(deleteButton); 

     TextBox textbox = textBoxes[rowid]; 
     MainGrid.Children.Remove(textbox); 
     textBoxes.RemoveAt(rowid); 

     ComboBox comboBox = comboBoxes[rowid]; 
     MainGrid.Children.Remove(comboBox); 
     comboBoxes.RemoveAt(rowid); 
    } 

    private void AddButton_Click(object sender, RoutedEventArgs e) { 
     addRow("", 1); 
    } 
    } 
} 

(テキストボックス、コンボボックス)あなたのウィンドウで使用します。表示するデータを含むそのクラスのコレクションを作成し、DataGridにバインドします。DataGridは、データを表示し、グリッドを使用するときに自分でプログラムしなければならない多くの機能を提供します。詳細については、私の記事を参照してください:Guide to WPF DataGrid formatting using bindings

+0

ありがとうございました。正確に私が探していたもの:) –

関連する問題