/ / wpf benutzt grid als Itemshost, um mehrere Items in einer 'Zelle' zu stapeln - wpf, grid, itemscontrol

wpf verwendet grid als itemshost und stapelt automatisch mehrere Elemente in einer 'Zelle' - wpf, grid, itemscontrol

Ich binde ein Artikel-Steuerelement an eine Datenquelle undVerwenden eines Rasters als mein Itemshost. Ich möchte, dass sich die Objekte in der richtigen Zelle des Gitters befinden (ich kann das tun) und sich auch stapeln, damit sie nicht alle übereinander liegen (ich kann nicht herausfinden, wie die Objekte in ein eingefügt werden Stackpanel oder ein anderes Panel im Raster).

Hier ist die CS-Datei für die beiden Klassen:

   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;
}
}
}

Hier ist mein 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>

Mein Problem ist, dass sich alle mit "a" endenden Schaltflächen unter den mit b endenden Schaltflächen befinden. Ich kann nicht sehen, wie XAML zum Einfügen der Elemente in ein dynamisch erstelltes Stackpanel verwendet wird

Ich habe versucht, eine von Grid abgeleitete Klasse zu erstellen,Der Gedanke, das Hinzufügen der Kinder abzufangen, um Stackpanels selbst hinzuzufügen und die Kinder dann vom Raster auf die Stackpanels zu verschieben, aber der Versuch, die Kinder in einem Itemshost zu manipulieren, löst eine Ausnahme aus.

Letztendlich möchte ich nur, dass die Elemente in meiner Datenquelle an eine "Zelle" im Raster gebunden werden können. Wenn mehrere Elemente an dieselbe Zelle gebunden werden, sollen sie gestapelt werden.

Antworten:

1 für die Antwort № 1

Sie können dies auf Datenebene wie HighCore tunvorgeschlagen, aber da die aktuelle Datenstruktur bereits die erforderlichen Informationen enthält, sollte es dem ItemsControl möglich sein, damit umzugehen. Erwägen Sie das Hinzufügen von a Gruppenbeschreibung zur Item Collection der ListBox und benutze a GroupStyle deren Panel ist ein StackPanel.


1 für die Antwort № 2

Hier ist die Lösung mit den Hinweisen von nmclean (Vielen Dank) In diesem Abschnitt wird die Gruppierung festgelegt, mit der die Elemente im Raster verteilt werden.

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


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


</CollectionViewSource.GroupDescriptions>

</CollectionViewSource>

Dieser Abschnitt ist das Hauptlistenfeld desDaten in der Datenquelle collectionviewsource, Der Containerstyle enthält die Bindungen, um das Gruppenelement in die richtigen Zellen im Raster zu setzen. Das Raster befindet sich im 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>

Hier ist die Gesamtlösung für den Fall, dass Sie es brauchen:

<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>

Die Code-Datei sieht jetzt so aus:

  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;
}

}