WPF: Create 8x8 TextBox table in codebehind - wpf

I need to create 8x8 TextBox table, each TextBox should be bound to element of double[,] array (i want to let user change matrix from ui).
What is the most elegant way to do this?

I would use an ItemsControl, and change the ItemPanel from the default StackPanel to a WrapPanel. Something like:
<ItemsControl>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
...
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>

Make use of a UniformGrid...
<UniformGrid>
<TextBox Text="{Binding SomeProperty}"/>
...
<TextBox Text="{Binding SomeProperty}"/>
</UniformGrid>
You may need to make use of an IValueConverter to deal with the way in which you are binding as well as setting the width and height to a fixed size to guarantee your 8x8 representation but the UniformGrid as a container should suffice to meet your goal of an 8x8 table.

Related

Items Box with limit of objects in row (Large icons view style in Windows Explorer)

Can't find a solution to a pretty simple UI problem:
I have a model with a Images property. The Images property holds a collection of items Image.
As for now on - I have a ListBox and binding a ListBoxItem data template to Images.Image and all good. But I have each item on a new line. Not good.
What I am willing to achieve is, lets describe as, a Listbox with Horizontal items orientation and limit of items in a row. Just like Large icons view style in Windows Explorer.
Have somebody previously implemented such a solution? Any advice will be highly appreciated.
Thank you in advance.
Use a WrapPanel (or some other appropriate Panel) as the ListBox's ItemsPanel, and disable horizontal scrolling:
<ListBox ItemsSource="{Binding Images}"
ScrollViewer.HorizontalScrollBarVisibility="Disabled">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemTemplate>
<DataTemplate>
<Image Source="{Binding}" Width="100" Margin="5"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
You can set the ListBox's ItemPanelTemplate to WrapPanel, like this.
I am not sure why it is always like that - but as soon as I asked, I have found an alternative solution with usage of ListView:
<ListView ItemsSource="{Binding Images}">
<ListView.ItemTemplate>
<DataTemplate>
<Image Source="{Binding Image}" />
</DataTemplate>
</ListView.ItemTemplate>
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid Columns="2" />
</ItemsPanelTemplate>
</ListView.ItemsPanel>
</ListView>

WPF itemscontrol child alignment

I have a WPF MVVM application with an itemscontrol. The number of horizontal child items is influenced by the itemscontrol width. There is only 1 thing i haven't solved. I'm trying to align the child elements in a way that there are always centered. I have made quick pictures in paint to demonstrate what i mean.
How it's now:
If the width further inceares then a forth item will be added horizontally. This function needs to stay.
How I would like to see it:
If there is enough room for a forth item then it needs to be added. I'm thinking that the answer could be a simple XAML property. Anybody an idea?
Put the ItemsControl in a Grid and set its HorizontalAlignment to Center:
<Grid>
<ItemsControl ItemsSource="{Binding Images}" HorizontalAlignment="Center">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Image Source="{Binding}" .../>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>

Looking for a WPF multicolumn list with scaling

I would like to create a multi-column list of checkboxes, but here's the catch - as I resize the window I would like everything to scale accordingly, including text size. I've been trying to make use of a WrapPanel and ViewBox but can't get the XAML right. Are these controls the best option or should I be using a ListBox (note I don't need selection functionality or scrollbars)? Any suggestions or examples on how I could achieve this would be much appreciated. I'm using MVVM and the list will be data bound, if that makes a difference.
BTW since starting WPF I've been struggling to understand which controls size to their children and which size to their parent. Are there any good sites, cheat sheets, or whatever summarising the behaviour of each control?
If you have a variable number of child elements, you could put a UniformGrid into a ViewBox.
If the child elements have to be visualized by a DataTemplate, you would have to use an ItemsControl with the ItemsPanel property set to such a UniformGrid:
<Viewbox Stretch="Uniform">
<ItemsControl ItemsSource="{Binding Items}" Width="400" Height="200">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid Columns="4"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Border Background="AliceBlue">
<CheckBox Content="{Binding Label}" IsChecked="{Binding IsChecked}"
HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Viewbox>

Alternate row color for a wrappanel

I am trying to get an alternate row color effect on a Listbox / wrappanel. However since the orientation is Horizontal, The alternate columns are getting the alternate colors. I want the elements to be listed side ways and then wrapped. How can I set the alternate color on rows based on this.
<ListBox ItemsSource="{Binding MySource}" ItemContainerStyle="{StaticResource alternatingListItemStyle}" AlternationCount="2">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Orientation="Horizontal" MaxWidth="300"/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemTemplate>
<DataTemplate>
<CheckBox Content="{Binding MyCaption}"/>
</DataTemplate>
</ListBox.ItemTemplate>
The possible reason for alternating color for columns is the 'MaxWidth'.
As the MaxWidth for WrapPanel is 300, it's possible to hold more than one item.
If you reduce the maxwidth, it may hold a single item.
Hope this helps.
(Can you explain why you are using a wrap panel in ItemsPanelTemplate?
I am not sure how you want the output to look like.)

How to set Height of items in XAML so they always occupy the same proportion of available space in parent ItemsControl?

I have an ItemsControl with the following ItemTemplate:
<DataTemplate x:Key="myItemTemplate">
<TextBlock Height="???" Text="{Binding Path=Description}" />
</DataTemplate>
My question is, how do I set the Height of the TextBlock in the template so that it automatically assumes ItemsControl.Height div ItemsCount amount of vertical space?
When there's only one item, I'd like it to be the full height of container, when there're two, each should be half the size, and so on.
If possible, I'd prefer to do this completely in XAML to keep my ViewModel clean of UI logic.
You could use a UniformGrid as your ItemsPanelTemplate and bind the Rows property to the number of items in your ItemsControl, like so:
<ItemsControl>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid Rows="{Binding Items.Count, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ItemsControl}}}" IsItemsHost="True"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
I did not test this code, so you need to check it, but I think the idea is clear.
EDIT: As pointed out by John below, this code is even easier:
<ItemsControl>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid Columns="1" IsItemsHost="True"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
I'm going to try and remember this as an intellectual exercise as I'm very new to WPF. I have no doubt I'll be corrected in due course. I think that you can specify a constant proportion by appending a % sign to the Height value i.e. Height="50%". This is deceptive, as it will add up all the numeric values of the heights of elements inside the parent, and size each one as its proportion of this sum. For example, three textblocks each of height="50%" would each have a height (50/150)*height of datatemplate = 1/3.

Resources