Vazba collectionviewsource v datagrid celltemplate

0

Otázka

Mám ožehavý problém a doufám, že vám může pomoci. Jsem vytvořit datagrid, který zahrnuje dynamicky vytváření sloupců. Tady je nějaké pseudokódu pro mé třídy:

GameLibrary
    ObservableCollection<Game> Games

Game
    ObservableCollection<CustomField> CustomFields

Customfield
    ObservableCollection<string> Values

Datagrid je vázán na CollectionViewSource, který používá GameLibrary.Hry, jako jeho Zdroj. Datagrid zobrazí další vlastnosti Hry v každé řadě, jak jsem se nastavit sloupce, a pak mám to dynamicky vytvořen sloupec pro každý CustomField v CustomFields a zobrazí příslušné CustomField Hodnoty v itemscontrol v buňce.

To vše funguje skvěle, žádný problém. Teď, když jsem chtěl seřadit Hodnoty podle abecedy zobrazení. Vím, že nejlepší praxe pro to je použití CollectionViewSource, a mně se podařilo získat jeden set, připojené k DataTemplate a zobrazování v itemscontrol - ale to funguje pouze v případě, jako test, jsem nastavit CVS zdrojový být něco mimo datagrid. To zobrazí, ale samozřejmě to zobrazuje stejnou věc v každém řádku.

Jak mohu svázat DataTemplate je CVS na něco, co v aktuálním řádku tabulky? Je to snadné, když není pomocí CVS, protože můžu použít závazné Cestu a jen říct, "CustomFields[i].Hodnoty", ale já nevím, jak se to překládá přes CVS Zdroj.

Tady je to, co mám teď, který funguje skvěle:

            FrameworkElementFactory listbox = new FrameworkElementFactory(typeof(ItemsControl));
            Binding b = new Binding();
            string pathb = "CustomFields[" + i + "].Values";
            b.Path = new PropertyPath(pathb);
            b.Mode = BindingMode.TwoWay;
            b.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
            listbox.SetBinding(ItemsControl.ItemsSourceProperty, b);
            listbox.SetValue(ItemsControl.PaddingProperty, new Thickness(5));
            dock.AppendChild(listbox);

            DataTemplate dt = new DataTemplate { VisualTree = dock };
            dt.Seal();
            newcolumn.CellTemplate = dt;
            gameDataDisplay.Columns.Add(newcolumn);

A tady je to, co chci:

            DataTemplate dt = new DataTemplate { VisualTree = dock };

            CollectionViewSource listboxCVS = new CollectionViewSource();
            SortDescription listboxsortDescription = new SortDescription(".", ListSortDirection.Ascending);
            listboxCVS.SortDescriptions.Add(listboxsortDescription);
            listboxCVS.Source = SOMETHING HERE BUT I DONT KNOW WHAT;
            dt.Resources.Add("customCVS" + i, listboxCVS);

            FrameworkElementFactory listbox = new FrameworkElementFactory(typeof(ItemsControl));
            Binding b = new Binding();
            b.Source = listboxCVS;
            listbox.SetBinding(ItemsControl.ItemsSourceProperty, b);
            listbox.SetValue(ItemsControl.PaddingProperty, new Thickness(5));
            dock.AppendChild(listbox);

            dt.Seal();
            newcolumn.CellTemplate = dt;
            gameDataDisplay.Columns.Add(newcolumn);

Také jsem se snažil místo pomocí CVS vazba na nemovitosti v CustomFields, že se vrátí seřazený seznam Hodnot, a to zobrazuje v pohodě, ale vím, že to není nejlepší praxe, a to nebude aktualizovat, dokud si vyhledejte položku offscreen a zpět, takže si myslím, že je to slepá ulička.

Děkuji vám za jakoukoli pomoc, kterou může nabídnout,

Tom.

PS: ObservableCollections zde nejsou striktně ObservableCollections, jsou odvozené třídě s pár extra metody, ale oni se chovají přesně stejné pro všechny praktické účely. Stačí zde zmínit pro úplnost.

binding c# datagrid wpf
2021-11-19 09:09:40
1

Nejlepší odpověď

0

Vyřešil jsem to jiným způsobem. Spíše než vytvoření nového datatemplate programově pro každou vlastní sloupec, jsem definovala datatemplate v okně zdroje pak používá ContentPresenter vyplnit vazby.

XAML:

<DataTemplate x:Key="customfieldtemplate">
    <DockPanel x:Name="customfieldHolder" VerticalAlignment="Center">
        <DockPanel.Resources>
            <CollectionViewSource x:Key="customfieldview" x:Name="customfieldview" Source="{Binding Values}">
                <CollectionViewSource.SortDescriptions>
                    <scm:SortDescription PropertyName="."/>
                </CollectionViewSource.SortDescriptions>
            </CollectionViewSource>
            <CollectionViewSource x:Key="customfieldsview" x:Name="customfieldsview" Source="{Binding PossibleValues}">
                <CollectionViewSource.SortDescriptions>
                    <scm:SortDescription PropertyName="."/>
                </CollectionViewSource.SortDescriptions>
            </CollectionViewSource>
        </DockPanel.Resources>

        <customcontrols:MultiComboBox Width="17" DockPanel.Dock="Right" Margin="5,0" ShowText="False" x:Name="customfieldMiniCombo" ItemsSource="{Binding Source={StaticResource customfieldsview}}" SelectedItems="{Binding Values}" SelectionMode="Multiple" BorderBrush="{DynamicResource MahApps.Brushes.TextBox.Border}" Background="{DynamicResource MahApps.Brushes.ThemeBackground}" Foreground="{DynamicResource MahApps.Brushes.Text}"/>

        <ItemsControl ItemsSource="{Binding Source={StaticResource customfieldview}}" Padding="5"/>
    </DockPanel>
</DataTemplate>

Codebehind:

        for (int i = 0; i < maindatafile.CurrentGameLibrary.CustomFields.Count; i++)
        {
            CustomColumn newcolumn = new CustomColumn();
            newcolumn.Header = maindatafile.CurrentGameLibrary.CustomFields[i].Name;

            gameDataDisplay.Columns.Add(newcolumn);

            var template = FindResource("customfieldtemplate");
            FrameworkElementFactory factory = new FrameworkElementFactory(typeof(ContentPresenter));
            factory.SetValue(ContentPresenter.ContentTemplateProperty, template);

            Binding newBinding = new Binding("CustomFields[" + i + "]");
            newBinding.Mode = BindingMode.TwoWay;
            newBinding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;

            factory.SetBinding(ContentPresenter.ContentProperty, newBinding);

            DataTemplate dt = new DataTemplate { VisualTree = factory };

            newcolumn.CellTemplate = dt;
        }

Na multicombobox user control (najdete zde) ve šablona obsahuje "povoleno" nastavení hodnot přidat do nebo odstranit z observablecollection. Jeho ItemsSource je další majetek v CustomField, jejíž getter vrací seznam přípustných hodnot pro daný CustomField. Na multicombobox je SelectedItems majetku používá stejné závazné jako ItemsControl.

Konečný výsledek? Buňka se zobrazí seznam hodnot, ve vhodné CustomField, s lil rozbalovací tlačítko vedle ní. Že rozevírací seznam obsahuje všechny možné hodnoty pro toto pole s těmi, které v současné době v seznamu vybrané. Seznam aktualizace žít, jak si vybrat a zrušit výběr hodnoty v tomto combobox, a také aktualizace žít, když tyto hodnoty jsou změněny v jiných částech programu.

2021-11-20 14:07:34

V jiných jazycích

Tato stránka je v jiných jazycích

Русский
..................................................................................................................
Italiano
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
हिन्दी
..................................................................................................................
Français
..................................................................................................................
Türk
..................................................................................................................
Português
..................................................................................................................
ไทย
..................................................................................................................
中文
..................................................................................................................
Español
..................................................................................................................
Slovenský
..................................................................................................................