/ / wpf używając siatki jako itemshost, automatycznie układając wiele elementów w pojedynczej `` komórce '' - wpf, grid, itemscontrol

wpf używa siatki jako itemshost automatycznie układając wiele elementów w pojedynczej „komórce” - wpf, grid, itemscontrol

Wiążę formant elementów ze źródłem danych iużywając siatki jako mojego itemshost. Chciałbym, aby elementy znajdowały się we właściwej komórce w siatce (mogę to zrobić), a także układają się w stos, aby nie były wszystkie jeden na drugim (nie mogę dowiedzieć się, jak wstawić elementy do stackpanel lub inny panel w siatce).

oto plik .cs dla dwóch klas:

   public class listofdata
{
public List<data> stuff { get; set; }
public listofdata()
{
stuff = new List<data>();
stuff.Add(new data(0, 0, "zeroa"));
stuff.Add(new data(0, 0, "zerob"));
stuff.Add(new data(1, 0, "onea"));
stuff.Add(new data(1, 0, "oneb"));
stuff.Add(new data(1, 1, "twoa"));
stuff.Add(new data(1, 1, "twob"));
}
}

public class data
{
public int x { set; get; }
public int y { set; get; }
public string text { get; set; }
public data(int x, int y, string text)
{
this.x = x;
this.y = y;
this.text = text;
}
}
}

Oto mój XAML

   <Window x:Class="GridTester.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

xmlns:src="clr-namespace:GridTester"
xmlns:sys="clr-namespace:System;assembly=mscorlib"

Title="MainWindow" >
<Window.Resources>
<DataTemplate DataType="{x:Type src:data}">
<Button Content="{Binding text}"/>
</DataTemplate>
<src:listofdata x:Key="MyDataSource"> </src:listofdata>


</Window.Resources>
<ListBox Name="Main" ItemsSource="{Binding Source={StaticResource MyDataSource},Path=stuff}">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<Grid Name="MyGrid">
<Grid.ColumnDefinitions>
<ColumnDefinition/>

<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
</Grid>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>

<ListBox.ItemContainerStyle>
<Style>
<Setter Property="Grid.Column" Value="{Binding x}"/>
<Setter Property="Grid.Row" Value="{Binding y}"/>
</Style>
</ListBox.ItemContainerStyle>

</ListBox>


</Window>

Mój problem polega na tym, że wszystkie przyciski kończące się na „a” znajdują się pod przyciskami kończącymi się na b. Nie widzę, jak używać XAML do wstawiania elementów do dynamicznie tworzonego panelu stosu

Próbowałem stworzyć klasę wywodzącą się z Grid,myślę o przechwyceniu dodawania dzieci w celu samodzielnego dodania paneli stosu, a następnie przeniesieniu dzieci z siatki do paneli stosu, ale próba manipulowania dziećmi w itemshost powoduje wyrzucenie wyjątku.

Ostatecznie chcę po prostu, aby elementy w moim źródle danych były w stanie powiązać się z „komórką” w siatce, a jeśli wiele elementów jest powiązanych z tą samą komórką, chcę, aby były ułożone w stos.

Odpowiedzi:

1 dla odpowiedzi № 1

Możesz to zrobić na poziomie danych, takim jak HighCoresugerowane, ale ponieważ obecna struktura danych zawiera już niezbędne informacje, ItemsControl powinien mieć możliwość ich obsługi. Rozważ dodanie opis grupy do kolekcji elementów ListBox i użyj pliku GroupStyle którego Płyta to StackPanel.


1 dla odpowiedzi nr 2

Oto rozwiązanie wykorzystujące wskazówki od nmclean (wielkie dzięki) Ta sekcja określa grupowanie, które będzie używane do rozmieszczania elementów w siatce.

<CollectionViewSource Source="{Binding Source={StaticResource MyDataSource}}" x:Key="cvs">


<CollectionViewSource.GroupDescriptions>
<PropertyGroupDescription PropertyName="ordinal"/>


</CollectionViewSource.GroupDescriptions>

</CollectionViewSource>

ta sekcja jest główną listą powiązaną zdata w pliku collectionviewsource, styl kontenera zawiera powiązania, które pozwalają umieścić element grupy w odpowiednich komórkach w siatce. Siatka znajduje się w pliku groupstyle.panel

  <ListBox  ItemsSource ="{Binding Source={StaticResource cvs}}"   >
<ListBox.GroupStyle>
<GroupStyle>
<GroupStyle.ContainerStyle>
<Style TargetType="{x:Type GroupItem}">
<Setter Property="Grid.Row" Value="{Binding Items[0].y,diag:PresentationTraceSources.TraceLevel=High}" />
<Setter Property="Grid.Column" Value="{Binding Items[0].x,diag:PresentationTraceSources.TraceLevel=High}" />


</Style>
</GroupStyle.ContainerStyle>
<GroupStyle.Panel>
<ItemsPanelTemplate>
<Grid>
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
</Grid.ColumnDefinitions>
</Grid>
</ItemsPanelTemplate>
</GroupStyle.Panel>
</GroupStyle>
</ListBox.GroupStyle>

Oto kompletne rozwiązanie na wypadek, gdybyś go potrzebował:

<Window x:Class="GridTester.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:diag="clr-namespace:System.Diagnostics;assembly=WindowsBase"
xmlns:src="clr-namespace:GridTester"
xmlns:sys="clr-namespace:System;assembly=mscorlib"

Title="Window1" Height="300" Width="300" Name="TOPWindow">
<Window.Resources>

<DataTemplate DataType="{x:Type src:data}">
<Button Content="{Binding text}"/>
</DataTemplate>
<src:listofdata x:Key="MyDataSource"></src:listofdata>
<CollectionViewSource Source="{Binding Source={StaticResource MyDataSource}}" x:Key="cvs">


<CollectionViewSource.GroupDescriptions>
<PropertyGroupDescription PropertyName="ordinal"/>


</CollectionViewSource.GroupDescriptions>

</CollectionViewSource>


</Window.Resources>



<ListBox  ItemsSource ="{Binding Source={StaticResource cvs}}"   >
<ListBox.GroupStyle>
<GroupStyle>
<GroupStyle.ContainerStyle>
<Style TargetType="{x:Type GroupItem}">
<Setter Property="Grid.Row" Value="{Binding Items[0].y,diag:PresentationTraceSources.TraceLevel=High}" />
<Setter Property="Grid.Column" Value="{Binding Items[0].x,diag:PresentationTraceSources.TraceLevel=High}" />


</Style>
</GroupStyle.ContainerStyle>
<GroupStyle.Panel>
<ItemsPanelTemplate>
<Grid>
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
</Grid.ColumnDefinitions>
</Grid>
</ItemsPanelTemplate>
</GroupStyle.Panel>
</GroupStyle>
</ListBox.GroupStyle>


</ListBox>



</Window>

Plik kodu wygląda teraz następująco:

  public class listofdata : List<data>
{

public listofdata()
{

Add(new data(0, 0, "zeroa"));
Add(new data(0, 0, "zerob"));
Add(new data(1, 0, "onea"));
Add(new data(1, 0, "oneb"));
Add(new data(1, 1, "twoa"));
Add(new data(1, 1, "twob"));


}

}

public class data
{
public int x { set; get; }
public int y { set; get; }
public int ordinal { get { return x * 1000 + y; } }
public string text { get; set; }
public data(int x, int y, string text)
{
this.x = x;
this.y = y;
this.text = text;
}

}