/ / wpf utilizza la griglia come itemshost che impila automaticamente più elementi in una singola "cella" - wpf, grid, itemscontrol

wpf utilizza la griglia come itemshost impilando automaticamente più elementi in una singola "cella" - wpf, grid, itemscontrol

Sto vincolando un controllo articoli a un'origine dati eusando una griglia come mio itemshost. Vorrei che gli oggetti si posizionassero nella cella corretta nella griglia (posso farlo) e anche impilarli in modo che non siano uno sopra l'altro (non riesco a capire come inserire gli oggetti in un stackpanel o altro pannello nella griglia).

ecco il file .cs per le due classi:

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

Ecco il mio 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>

Il mio problema è che tutti i pulsanti che terminano con "a" si trovano sotto i pulsanti che terminano con b. Non riesco a vedere come usare XAML per inserire gli elementi in uno stackpanel creato dinamicamente

Ho provato a creare una classe derivata da Grid,pensando di intercettare l'aggiunta dei bambini per aggiungere io stesso i pannelli di controllo e quindi spostare i bambini dalla griglia ai pannelli di controllo, ma il tentativo di manipolare i bambini in un oggetti host provoca l'eccezione.

In definitiva, voglio solo che gli oggetti nella mia origine dati siano in grado di legarsi a una "cella" nella griglia e se più elementi si legano alla stessa cella, voglio che vengano impilati.

risposte:

1 per risposta № 1

Potresti farlo a livello di dati come HighCoresuggerito, ma poiché l'attuale struttura di dati contiene già le informazioni necessarie, dovrebbe essere possibile per ItemsControl gestirlo. Valuta di aggiungere a Descrizione del gruppo alla raccolta di articoli di ListBox e utilizzare a GroupStyle di chi Pannello è uno StackPanel.


1 per risposta № 2

Ecco la soluzione usando i suggerimenti di nmclean (Grazie mille) Questa sezione stabilisce il raggruppamento che verrà utilizzato per distribuire gli elementi attorno alla griglia.

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


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


</CollectionViewSource.GroupDescriptions>

</CollectionViewSource>

questa sezione è la casella di riepilogo principale associata adata in collectionviewsource, Il containertyle contiene i collegamenti per inserire il groupitem nelle celle corrette nella griglia. La griglia è in 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>

Ecco la soluzione totale nel caso in cui ne abbiate bisogno:

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

Il file di codice ora è simile al seguente:

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

}