ComboBoxを含むDataGridCellがあります。
その「SelectionChanged」イベントを発生させたときに、別の列(最終的には実行時のセル)のCollectionViewSourceに、この行で選択した値に従ってデータを入力する必要があります。
多分DataTrigger、ActionTrigger、EventTrigger、多分コード、XAML私は気にしない、私はただ解決策が必要です。
どうもありがとう!
ComboBoxを含むDataGridCellがあります。
その「SelectionChanged」イベントを発生させたときに、別の列(最終的には実行時のセル)のCollectionViewSourceに、この行で選択した値に従ってデータを入力する必要があります。
多分DataTrigger、ActionTrigger、EventTrigger、多分コード、XAML私は気にしない、私はただ解決策が必要です。
どうもありがとう!
私があなたの質問を正しく理解している場合は、DataGridの同じ行にある別のセルのコンボボックスの選択に基づいて、セルのコンボボックスの内容を入力します。そうであれば:
最初の解決策(IMOが望ましい)
行データ(データオブジェクトの単純なラッパー)を表すViewModelを作成します。宛先ComboBoxのItemsSource-propertyを、IEnumerable
ビューモデルから提供する-propertyにバインドします。SelectedItemをsource-ComboBoxからViewModelの別のプロパティにバインドします。このソースプロパティがViewModelで変更されるたびに、ViewModelによって提供されるリストの内容を変更します。
宛先(リスト)プロパティに使用しますObservableCollection<T>
。ソースプロパティはあなた次第です。
これはおおよその例です。私はクラスVM(ViewModel用)と呼んでいますが、これは現在のソリューションでは何も変わりません。MVVMは部分的に使用することもできます。
public class DataObjectVM : DependencyObject {
public static readonly DependencyProperty SelectedCategoryProperty =
DependencyProperty.Register("SelectedCategory", typeof(CategoryClass), typeof(DataObjectVM), new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault,delegate (DependencyObject d,DependencyPropertyChangedEventArgs e){
((DataObjectVM)d).SelectedCategoryChanged(e);
}));
ObservableCollection<ItemClass> _items=new ObservableCollection<ItemClass>();
void SelectedCategoryChanged(DependencyPropertyChangedEventArgs e) {
// Change here the contents of the _items collection.
// The destination ComboBox will update as you desire
// Do not change the _items reference. Only clear, add, remove or
// rearange the collection-items
}
// Bind the destination ComboxBox.ItemsSource to this property
public IEnumerable<ItemClass> DestinationItems {
get {
return _items;
}
}
// Bind to this property with the source ComboBox.SelectedItem
public CategoryClass SelectedCategory {
get { return (CategoryClass)GetValue(SelectedCategoryProperty); }
set { SetValue(SelectedCategoryProperty, value); }
}
}
このクラスにコンストラクターを追加して、データオブジェクトを取得し、いくつかのラッパープロパティを作成して、残りのプロパティをDataGridで提供する必要があります。それらがたくさんある場合は、データオブジェクトとそれに直接バインドするプロパティを1つ作成することもできます。良くありませんが、それは仕事をします。また、ビジネスオブジェクトのデータを使用してSelectedCategoryを事前に初期化することもできます(必須)。コンストラクターでもこれを行います。DataGridのItemsSourceとして、表示するすべてのアイテムをラップするDataObjectVMクラスのIEnumerableを指定します。
VisualTreeHelperを使用した別の方法
手動で実行する場合は、ComboBox.SelectionChangedEventのハンドラーの背後にあるコードに登録し、宛先のComboBox手動のItemsSourceを変更します。EventArgsで取得するビジネスオブジェクト。ビジュアルツリーで検索する必要のある宛先ComboBox(VisualTreeHelperを使用)。クラスを使用し、対応するComboBoxでDataGridTemplateColumn
を追加する場合も、イベントを配線できます。DataTemplate
しかし、これは実際にはそれほど簡単ではなく、エラーが発生しやすいと思います。上記の解決策ははるかに簡単です。
これがあなたがおそらく探しているコードです:
private void CboSource_SelectionChanged(object sender, SelectionChangedEventArgs e) {
ComboBox cbo = (ComboBox)sender;
FrameworkElement currentFe = VisualTreeHelper.GetParent(cbo) as FrameworkElement;
while (null != currentFe && !(currentFe is DataGridRow)) {
currentFe = VisualTreeHelper.GetParent(currentFe) as FrameworkElement;
}
if (null != currentFe) {
List<ComboBox> list = new List<ComboBox>();
FindChildFrameworkElementsOfType<ComboBox>(currentFe,list);
// Requirement 1: Find ComboBox
foreach (ComboBox cboFound in list) {
if (cboFound.Name == "PART_CboDestination") {
// This is the desired ComboBox
// Your BO is available through cbo.Found.DataContext property
// If don't like to check the name, you can also depend on the
// sequence of the cbo's because I search them in a deep search
// operation. The sequence will be fix.
}
}
List<DataGridCell> cells = new List<DataGridCell>();
FindChildFrameworkElementsOfType<DataGridCell>(currentFe,cells);
// Requirement 2: Find Sibling Cell
foreach (DataGridCell cell in cells) {
// Here you have the desired cell of the other post
// Take the sibling you are interested in
// The sequence is as you expect it
DataGridTemplateColumn col=cell.Column as DataGridTemplateColumn;
DataTemplate template = col.CellTemplate;
// Through template.Resources you can access the CollectionViewSources
// if they are placed in the CellTemplate.
// Change this code if you will have an edit cell template or another
// another construction
}
}
}
void FindChildFrameworkElementsOfType<T>(DependencyObject parent,IList<T> list) where T: FrameworkElement{
DependencyObject child;
for(int i=0;i< VisualTreeHelper.GetChildrenCount(parent);i++){
child = VisualTreeHelper.GetChild(parent, i);
if (child is T) {
list.Add((T)child);
}
FindChildFrameworkElementsOfType<T>(child,list);
}
}
そして、これは私が使用したマークアップです:
<DataGrid.Columns>
<DataGridTemplateColumn Header="Source" >
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ComboBox Name="PART_CboSource" SelectionChanged="CboSource_SelectionChanged" ItemsSource="!!YOUR ITEMS SOURCE!!" SelectedItem="{Binding Category}">
</ComboBox>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Header="Destination">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ComboBox Name="PART_CboDestination"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
CollectionViewSourceへのアクセス
CollectionViewSourceにアクセスするには、パネルではなく、対応するDataTemplateのリソースセクションに配置します。そうすれば、それらに直接アクセスできます。IMOは、グリッドのリソースコンテナよりも適切なこの場所です。
これを行いたくない場合は、次の投稿の状態を確認してください。