0

私は、最初のComboBoxが、2番目のComboBoxがバインドされているIDを変更するDataTemplateSelectorを使用して変更するWPF 4 DataGridを持っています。何らかの奇妙な理由で、同じタイプの2番目の列にあるセルは、同じ値にバインドされているようです。私は前にこの問題を見てきたように、DataTemplateを使用することに関連していると信じていますが、明らかに私が知る必要があることを理解していません。異なるDataGrid行にわたるDataTemplateの複製

MainWindow.xaml:それは誰かを助けた場合の解決策を見つけた

<Window x:Class="WpfApplication1.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:local="clr-namespace:WpfApplication1" Title="MainWindow" Height="300" Width="300" Loaded="WindowLoaded"> 
    <Window.Resources> 
     <CollectionViewSource x:Key="MainSource" /> 
     <CollectionViewSource x:Key="TypeSource" /> 
     <CollectionViewSource x:Key="DaysInMonthSource" /> 
     <CollectionViewSource x:Key="DaysInWeekSource" /> 

     <local:TypeSelector x:Key="cbTypeSelector"> 
      <local:TypeSelector.EmptyTemplate> 
       <DataTemplate x:Name="Emptied"> 
        <Grid></Grid> 
       </DataTemplate> 
      </local:TypeSelector.EmptyTemplate> 
      <local:TypeSelector.DaysInWeekTemplate> 
       <DataTemplate> 
        <ComboBox SelectedValue="{Binding Path=dayNumber, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, NotifyOnSourceUpdated=True}" 
           ItemsSource="{Binding Source={StaticResource DaysInWeekSource}}" 
           DisplayMemberPath="name" SelectedValuePath="id" Name="cb" Padding="3,2,3,3" /> 
       </DataTemplate> 
      </local:TypeSelector.DaysInWeekTemplate> 
      <local:TypeSelector.DaysInMonthTemplate> 
       <DataTemplate> 
        <ComboBox SelectedValue="{Binding Path=dayNumber, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, NotifyOnSourceUpdated=True}" 
           ItemsSource="{Binding Source={StaticResource DaysInMonthSource}}" 
           DisplayMemberPath="name" SelectedValuePath="id" Name="cb" Padding="3,2,3,3" /> 
       </DataTemplate> 
      </local:TypeSelector.DaysInMonthTemplate> 
     </local:TypeSelector> 
    </Window.Resources> 
    <Grid> 
     <DataGrid AutoGenerateColumns="False" Name="DataGrid1" CanUserAddRows="True" SelectionMode="Single" 
        EnableColumnVirtualization="True" EnableRowVirtualization="True" > 
      <DataGrid.Columns> 
       <DataGridComboBoxColumn 
        Header="Type" IsReadOnly="False" 
        DisplayMemberPath="name" SelectedValuePath="id" SelectedValueBinding="{Binding Path=type_id, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, NotifyOnSourceUpdated=True}" 
        ItemsSource="{Binding Source={StaticResource TypeSource}}"> 
       </DataGridComboBoxColumn> 
       <DataGridTemplateColumn Header="Day" IsReadOnly="False"> 
        <DataGridTemplateColumn.CellTemplate> 
         <DataTemplate> 
          <ContentPresenter local:Helper.UpdateTrigger="{Binding Path=type_id}" ContentTemplateSelector="{StaticResource cbTypeSelector}"/> 
         </DataTemplate> 
        </DataGridTemplateColumn.CellTemplate> 
       </DataGridTemplateColumn> 
      </DataGrid.Columns> 
     </DataGrid> 
    </Grid> 
</Window> 

MainWindow.xaml.cs

using System.Collections.Generic; 
using System.Globalization; 
using System.Linq; 
using System.Windows; 
using System.Windows.Controls; 
using System.Windows.Data; 
using System.Windows.Media; 

namespace WpfApplication1 
{ 

    public class DayContainer 
    { 
     public int id { get; set; } 
     public string type_id { get; set; } 
     public string dayNumber { get; set; } 
    } 

    public class TypeSelector : DataTemplateSelector 
    { 
     public DataTemplate EmptyTemplate { get; set; } 
     public DataTemplate DaysInWeekTemplate { get; set; } 
     public DataTemplate DaysInMonthTemplate { get; set; } 

     public override DataTemplate SelectTemplate(object item, DependencyObject container) 
     { 
      var element = container as FrameworkElement; 
      if (element == null || item == null) return EmptyTemplate; 
      var dgr = FindVisualParent<DataGridRow>(element); 
      var drv = dgr.Item as DayContainer; 
      if (drv == null) return EmptyTemplate; 
      if (drv.type_id == "1") 
       return DaysInWeekTemplate; 
      if (drv.type_id == "2") 
       return DaysInMonthTemplate; 
      return EmptyTemplate; 
     } 

     public static T FindVisualParent<T>(UIElement element) where T : UIElement 
     { 
      var parent = element; 
      while (parent != null) 
      { 
       var correctlyTyped = parent as T; 
       if (correctlyTyped != null) return correctlyTyped; 
       parent = VisualTreeHelper.GetParent(parent) as UIElement; 
      } 
      return null; 
     } 
    } 

    public class Helper 
    { 
     public static object GetUpdateTrigger(DependencyObject obj) 
     { 
      return obj.GetValue(UpdateTriggerProperty); 
     } 
     public static void SetUpdateTrigger(DependencyObject obj, object value) 
     { 
      obj.SetValue(UpdateTriggerProperty, value); 
     } 
     public static readonly DependencyProperty UpdateTriggerProperty = 
      DependencyProperty.RegisterAttached("UpdateTrigger", typeof(object), typeof(Helper), new FrameworkPropertyMetadata(OnUpdateTriggerChanged)); 
     public static void OnUpdateTriggerChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
     { 
      var cp = d as ContentPresenter; 
      if (cp == null) return; 
      var temp = cp.Content; 
      cp.Content = null; 
      cp.Content = temp; 
     } 
    } 

    public partial class MainWindow 
    { 
     public MainWindow() 
     { 
      InitializeComponent(); 
     } 

     private void WindowLoaded(object sender, RoutedEventArgs e) 
     { 
      var source = (CollectionViewSource)FindResource("MainSource"); 
      source.Source = new List<DayContainer> 
           { 
            new DayContainer {id = 1, type_id = "1", dayNumber = "1"}, 
            new DayContainer {id = 2, type_id = "1", dayNumber = "2"}, 
            new DayContainer {id = 3, type_id = "2", dayNumber = "3"}, 
           }; 
      DataGrid1.ItemsSource = source.View; 

      source = (CollectionViewSource)FindResource("TypeSource"); 
      if (source != null && source.Source == null) 
       source.Source 
        = new[] 
          { 
           new {id = "1", name = "Week"}, 
           new {id = "2", name = "Month"} 
          }; 


      source = (CollectionViewSource)FindResource("DaysInWeekSource"); 
      if (source != null && source.Source == null) 
       source.Source 
        = new[] 
          { 
           new {id = "1", name = "Sunday"}, 
           new {id = "2", name = "Monday"}, 
           new {id = "3", name = "Tuesdsay"}, 
           new {id = "4", name = "Wedsnesday"}, 
           new {id = "5", name = "Thursday"}, 
           new {id = "6", name = "Friday"}, 
           new {id = "7", name = "Saturday"} 
          }; 


      source = (CollectionViewSource)FindResource("DaysInMonthSource"); 
      if (source != null && source.Source == null) 
       source.Source = from n in Enumerable.Range(1, 31) 
           select new { id = n.ToString(CultureInfo.InvariantCulture), name = n.ToString(CultureInfo.InvariantCulture) }; 
     } 
    } 

} 

答えて

0

ここ

は、私がこれまでに組み立てられたコードです。

IsSynchronizedWithCurrentItem = "False"を各ComboBoxに追加するだけです。

関連する問題