شبكة بيانات WPF:DataGridComboxBox ItemsSource ملزمة لمجموعة من المجموعات

StackOverflow https://stackoverflow.com/questions/1633800

سؤال

الموقف:

لقد قمت بإنشاء DataGrid في XAML وتم ربط ItemsSource بـ ObservableCollection لفئة معينة تحتوي على خصائص.ثم في C#، قمت بإنشاء DataGridTextColumn وDataGridComboBoxColumn وربطهما بخصائص الكائنات الموجودة داخل ObservableCollection.يمكنني ربط DataGridComboBoxColumn بمجموعة بسيطة ولكن ما أريد القيام به هو ربطه بمجموعة من مجموعات السلاسل بحيث يحتوي ComboBox داخل DataGrid على مجموعة مختلفة من السلاسل لكل صف.لقد فشلت في فعل ذلك..

سؤال:

كيف يمكنني ربط DataGridCombBoxColumn حتى أتمكن من الحصول على مجموعة مختلفة من السلاسل لكل صف من هذا النوع من الأعمدة؟

نموذج التعليمات البرمجية:

XAML:

<Window>
  <!-- ... -->
  WPFToolkit:DataGrid
           x:Name="DG_Operations"
           Margin="10,5,10,5" 
           Height="100" 
           HorizontalAlignment="Stretch" 
           FontWeight="Normal" 
           ItemsSource="{Binding Path=OperationsStats}"
           AlternatingRowBackground="{DynamicResource SpecialColor}" 
           HorizontalScrollBarVisibility="Auto" 
           VerticalScrollBarVisibility="Visible" 
           SelectionMode="Extended"
           CanUserAddRows="False" 
           CanUserDeleteRows="False"
           CanUserResizeRows="True" 
           CanUserSortColumns="True"
           AutoGenerateColumns="False" 
           IsReadOnly="False" 
           IsEnabled="True"
           BorderThickness="1,1,1,1" 
           VerticalAlignment="Stretch"/>
  <!-- ... -->
</Window>

ج#:

public class DataModelStatsOperations
{
   public ObservableCollection<IStatsOperation> OperationsStats { get; set; }
}

public interface IStatsOperation
{
   string Operation { get; set; }
   Collection<string> Data{ get; set; }
}

public class StatsOperation : IStatsOperation
{
    public StatsOperation(string operation, Collection<string> data)
    {
        Operation = operation;
        Data = data;
    }
    public string Operation { get; set; }
    public Collection<string> Data{ get; set; }
}

private ObservableCollection<IStatsOperation> dataOperations_ =
        new ObservableCollection<IStatsOperation>();

//...
 Binding items = new Binding();
 PropertyPath path = new PropertyPath("Operation");
 items.Path = path;
 DG_Operations.Columns.Add(new DataGridTextColumn()
 {
     Header = "Operations",
     Width = 133,
     Binding = items
  });
  DG_Operations.Columns.Add(new DataGridComboBoxColumn()
  {
     Header = "Data",
     Width = 190,
     ItemsSource = /*???*/,
     SelectedValueBinding = new Binding("Data"),
     TextBinding = new Binding("Data")
  });
dataOperations_.Add(new StatsOperation(CB_Operation.SelectedItem.ToString(),
                                                           dataCollection));
DG_Operations.DataContext = new DataModelStatsOperations
{
    OperationsStats = dataOperations_
};
//...

سيكون موضع تقدير كبير أي مساعدة!

ملحوظات:

حسنًا، بعد قراءة الإجابتين الأوليين لاحظت شيئًا ما.ربطي ليس صحيحًا حقًا!الآن، ما أريد القيام به هو شيء مشابه لما اقترحه AndyG:

DG_Operations.Columns.Add(new DataGridComboBoxColumn()
{
    Header = "Data",
    Width = 190,
    ItemsSource = new Binding("Data"), //notice this here does not work (have a look at the following error)
    SelectedValueBinding = new Binding("Operation"),
    TextBinding = new Binding("Operation")
});

خطأ:"لا يمكن تحويل النوع 'System.Windows.Data.Binding' ضمنيًا إلى 'System.Collections.IEnumerable'."

كيف يمكن ربط ItemsSource بالبيانات؟

هل كانت مفيدة؟

المحلول

أولاً، يجب أن يكون هذا سهلاً..ثانيًا، لماذا تقوم ببناء (وربط) الأعمدة في لغة C#؟إيك.

XAML (أنا أستخدم شبكة عادية لأنني كسول):

<ListView Name="MyListView">
    <ListView.View>
        <GridView>

            <GridView.Columns>

                <GridViewColumn DisplayMemberBinding="{Binding Operation}" />

                <GridViewColumn>
                    <GridViewColumn.CellTemplate>
                        <DataTemplate>
                            <ComboBox ItemsSource="{Binding Choices}" />
                        </DataTemplate>
                    </GridViewColumn.CellTemplate>
                </GridViewColumn>

            </GridView.Columns>

        </GridView>
    </ListView.View>
</ListView>

ج #:

void Window1_Loaded(object sender, RoutedEventArgs e)
{
    var dahList = new List<StatsOperation>();

    dahList.Add(new StatsOperation
    {
        Operation = "Op A",
        Choices = new string[] { "One", "Two", "Three" },
    });

    dahList.Add(new StatsOperation
    {
        Operation = "Op B",
        Choices = new string[] { "4", "5", "6" },
    });

    this.MyListView.ItemsSource = dahList;
}

النتائج:

شبكة WPF مع خيارات مربع التحرير والسرد الديناميكي http://www.singingeels.com/Articles/Articles/UserImage.aspx?ImageID=b1e3f880-c278-4d2b-bcc2-8ad390591200

نصائح أخرى

أعتقد أن الخطأ يكمن في كيفية قيامك بالربط.عندما تقوم بتعريف عمود، يرتبط الارتباط بالكائن الذي يمثله صف معين.كما أفهم، لديك StatsOperation لكل صف، وبالتالي فإن عمود TextBox مرتبط بالعملية، وهذه هي الطريقة التي لديك بها، ويجب أن يكون عمود ComboBox ItemsSource مرتبطًا بمجموعة.يبدو الآن أنه مرتبط بـ a Collection<Collection<string>>.

لم أقم بتعريف الأعمدة في التعليمات البرمجية الخلفية من قبل، لذا إليك مثال في XAML.لقد وجدت أن ComboBoxColumn يمكن أن يكون صعبًا في بعض الأحيان، لذا فقد أوضحت كيف يمكنك الحصول على combobox في العمود باستخدام إما TemplateColumn أو ComboBoxColumn.لقد قمت بنسخ ولصق من الكود الخاص بي لذا فقط استبدل "dg" بـ "WPToolkit" في حالتك:

<dg:DataGrid
      ...
      ...>
      <dg:DataGrid.Columns>
            <dg:DataGridTextColumn Binding="{Binding Operation}" CanUserReorder="True" CanUserResize="True" Header="Operation" />
            <dg:DataGridTemplateColumn CanUserReorder="True" CanUserResize="True" Header="Template Column">
                <dg:DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <ComboBox ItemsSource="{Binding Data}" SelectedItem="{Binding Operation}" />
                    </DataTemplate>
                </dg:DataGridTemplateColumn.CellTemplate>
            </dg:DataGridTemplateColumn>
            <dg:DataGridComboBoxColumn
                Header="ComboBox Column"                                                                                    
                 SelectedValueBinding="{Binding Operation}"                     
                 SelectedItemBinding="{Binding Operation}">
                <dg:DataGridComboBoxColumn.ElementStyle>
                    <Style TargetType="ComboBox">
                        <Setter Property="IsSynchronizedWithCurrentItem" Value="False" />
                        <Setter Property="ItemsSource" Value="{Binding Data}" />
                    </Style>
                </dg:DataGridComboBoxColumn.ElementStyle>
                <dg:DataGridComboBoxColumn.EditingElementStyle>
                    <Style TargetType="ComboBox">
                        <Setter Property="ItemsSource" Value="{Binding Data}" />
                        <Setter Property="IsDropDownOpen" Value="True" />
                    </Style>
                </dg:DataGridComboBoxColumn.EditingElementStyle>
            </dg:DataGridComboBoxColumn>
      </dg:DataGrid.Columns>

</dg:DataGrid>

أفترض أن العملية هي العنصر المحدد، والبيانات هي العناصر التي سيتم الاختيار من بينها، وأن DataGrid الخاص بك مرتبط بمجموعة StatsOperation.حظ سعيد!

لإصلاح خطأ ربط ItemsSource، استخدم النموذج:

BindingOperations.SetBinding(new DataGridComboBoxColumn(), DataGridComboBoxColumn.ItemsSourceProperty, new Binding("Data"));

من الواضح أنك لا تستطيع القيام بذلك في أداة التهيئة لذا سيتعين عليك تحريك إعلاناتك قليلاً ولكن هذا يجب أن يعتني بهذا الخطأ في التحديث الخاص بك.

يحرر أنا آسف، أنا بطيء بعض الشيء في منتصف الليل :).هنا إجابة محدثة.يبدو وكأنه مقال عظيم من فنسنت سيبال WPF DataGrid - مقدمة DataGridComboBoxColumn v1 يجيب على سؤالك.هل هو كذلك؟

جزئيا - أعتقد أن هناك لبسا في ما تقوله.لقد قلت أنك بحاجة إلى مجموعة من السلاسل في كل صف حتى يتمكن مربع التحرير والسرد من إظهار سلاسل مختلفة لصفوف مختلفة.ومع ذلك، لكي يعرض مربع التحرير والسرد مجموعة من السلاسل، فأنت تحتاج فقط إلى مجموعة من السلاسل، لكل صف، وليس مجموعة من السلاسل.

الآن، بما أنك تحتاج إلى مجموعة السلاسل لكل صف، فقد تفكر في أنك ستحتاج إلى مجموعة من السلاسل.

هل فهمي لسؤالك صحيح؟إذا كان الأمر كذلك، فذكرك لمجموعة مجموعة السلاسل خاطئ.

ما تحتاجه بالفعل هو مجموعة من عمليات StatOperations حيث يجب أن تحتوي كل عملية StatOperation على مجموعة من السلاسل.هذا هو بالضبط ما حدث كما هو موضح في فصولك أعلاه.

لإحراز تقدم، أقترح عليك تعديل سؤالك والإشارة إلى المكان الذي توقفت فيه بالضبط بعد إصلاح الارتباط كما اقترح AndyG.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top