UniformGrid Grid.Row Grid.Column not being adhered to - c#

Following on from this question (DataTemplateSelector for Uniform Grid binding?), I still am not getting my Buttons/Textblocks to adhere to the row and the column that they are bound to in the view model. I will only post the XAML as I know the row and column bindings are correct (Live Visual Tree tells me Row is 1 and Column is 1 for example, but on the grid it shows otherwise...).
If you need anymore code let me know. This is the small bit of XAML.
<Grid DockPanel.Dock="Left" Background="Transparent" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" MinWidth="800" Height="400">
<ItemsControl ItemsSource="{Binding ObjCompositeCollection}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid DockPanel.Dock="Top" HorizontalAlignment="Stretch"
VerticalAlignment="Stretch" Name="objGrid" Grid.Row="1"
Rows="{Binding RowCount}"
Columns="{Binding ColumnCount}"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemContainerStyle>
<Style>
<Setter Property="Grid.Row" Value="{Binding Row}"/>
<Setter Property="Grid.Column" Value="{Binding Column}"/>
</Style>
</ItemsControl.ItemContainerStyle>
<ItemsControl.Resources>
<DataTemplate DataType="{x:Type engine:ObjA}">
<Button Content="{Binding Id}" />
</DataTemplate>
<DataTemplate DataType="{x:Type engine:GridLabeller}">
<TextBlock Text="{Binding HeaderName}"/>
</DataTemplate>
</ItemsControl.Resources>
</ItemsControl>
</Grid>

A UniformGrid in WPF doesn't care about the Grid.Row and Grid.Column attached properties. You need to create a Grid with RowDefinitions and ColumnsDefinitions for setting these properties to have any effect.
You may create a Grid programmatically in the view based on the values of the RowCount and ColumnCount source properties.

Related

How to add a WPF Button to add content to a List inside an ObservableCollection?

From a Database I am receiving a List with multiple Properties. One of those Properties is again a List of an Appendix Object containing ID Information and an Image.
I converted that List into an ObservableCollection and bound it to a WPF ListBox. Using a DataTemplate I show this content. Inside the DataTemplate I now have an ItemControl bound to the Inner-List (my Appendix with none, one or multiple entries):
<ListBox ItemsSource="{Binding Reports}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Vertical">
<StackPanel Orientation="Horizontal">
<Label Content="Report Date:" FontWeight="Bold"/>
<Label Content="{Binding ReportDate.Date, StringFormat=dd.MM.yyyy , ConverterCulture=de-DE}"/>
<Label Content="Comment:" FontWeight="Bold"/>
<Label Content="{Binding Comment}"/>
</StackPanel>
//Here I would like to have a Button to add a Picture into the Appendix List
<ItemsControl x:Name="SelectedOnlyListBox" ItemsSource="{Binding Appendix}" Visibility="Collapsed">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel IsItemsHost="True" Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Image Source="{Binding Picture}"/>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ListBoxItem}, AncestorLevel=1}, Path=IsSelected}" Value="True">
<Setter Property="Visibility" Value="Visible" TargetName="SelectedOnlyListBox" />
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</ListBox.ItemTemplate>
My question is, how do I get the current Object via Binding into my Code. Because I will have multiple Buttons for one outer List (Reports) entry. But the Button should only add into the proper Inner List (Appendix).
Additional info: I am using the MVVM-Light Toolkit.
Thank you very much.
Edit: I forgot to mention that the first List is one of many Properties of a Detail class which again comes in a List of all Details. So with my DataContext already got a Property "SelectedDetail". This one I know...
But how do I now match the specific Button of each SelectedDetail.Report to my SelectedDetail.Reports.Appendix?

How to give dynamic width to gridview items (text block)?

I am developing a Windows 10 UWP, and a Windows Phone 8.1 project. In the project, there are tags like in Instagram, which can be seen in the picture. These tags are printed on the screen using a GridView. The problem is that I couldn't make the GridView items' width dynamic by their content. It takes the first item's width and gives all the other items the same width. For the shorter words, it's not a problem but some letters of the longer words are not visible.
Here is a screen shot of the problem.
The code I wrote;
<GridView SelectionMode="None" ItemsSource="{Binding TagsArray}" ScrollViewer.IsHorizontalRailEnabled="True">
<GridView.ItemTemplate>
<DataTemplate>
<Grid>
<TextBlock x:Name="tagButton" Tapped="tagButton_Tapped" FontWeight="Medium" Text="{Binding}" Foreground="#063076" FontSize="11" HorizontalAlignment="Left"/>
</Grid>
</DataTemplate>
</GridView.ItemTemplate>
<GridView.ItemContainerStyle>
<Style TargetType="GridViewItem">
<Setter Property="Margin" Value="0,-15,0,-15"/>
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
</Style>
</GridView.ItemContainerStyle>
<GridView.ItemsPanel>
<ItemsPanelTemplate>
<ItemsWrapGrid Orientation="Horizontal"/>
</ItemsPanelTemplate>
</GridView.ItemsPanel>
</GridView>
I would recommend you to use WrapPanel from UWP Community Toolkit for this.
You can use it inside the GridView by replacing the ItemsPanel:
<GridView.ItemsPanel>
<ItemsPanelTemplate>
<toolkit:WrapPanel Orientation="Horizontal" AllowDrop="True">
</toolkit:WrapPanel>
</ItemsPanelTemplate>
</GridView.ItemsPanel>
Here's a full example:
<GridView x:Name="ItemGrid" Width="450" HorizontalAlignment="Left" VerticalAlignment="Bottom">
<GridView.ItemTemplate>
<DataTemplate >
<TextBlock Text="{Binding}"/>
</DataTemplate>
</GridView.ItemTemplate>
<GridView.ItemsPanel>
<ItemsPanelTemplate>
<controls:WrapPanel Orientation="Horizontal" AllowDrop="True">
</controls:WrapPanel>
</ItemsPanelTemplate>
</GridView.ItemsPanel>
</GridView>
When used with the following collection:
var ite = new ObservableCollection<string>();
ite.Add("#tag1");
ite.Add("#a");
ite.Add("#tag3");
ite.Add("#differ");
ite.Add("#tag5");
ite.Add("#longertag");
ite.Add("#verylongtag");
ite.Add("#tag1");
this.ItemGrid.ItemsSource = ite;
Provides the following output:

How can i make a ListView's items take up all the available height?

I am trying to make a column chart using WPF. For the Y axis I have a list of values which I would like to display on the control.
I have a ListView bound to the collection. How can I get the items to spread over the entire length of the list view rather then squish together at the top? And is the ListViewthe correct control to use for this?
Here is a sample of my Xaml:
<ListView Grid.Row="1" Grid.Column="1" Grid.RowSpan="2"
ItemsSource="{Binding YAxisValues}"
Background="Gray" VerticalContentAlignment="Stretch">
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Label Content="{Binding Path=Value}"
Foreground="White"
HorizontalAlignment="Left"
FontSize="12" Width="50"/>
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
On the left is the list view as i currently have it.
On the right is my desired result.
How can I change my ListView to get there? Or do I need to use a different control entirely?
with UniformGrid used as ItemsPanel items get equal height
<ListView Name="Axis" Grid.Row="1" Grid.Column="1" Grid.RowSpan="2"
ItemsSource="{Binding YAxisValues}"
Background="Gray" VerticalContentAlignment="Stretch"
ScrollViewer.VerticalScrollBarVisibility="Disabled">
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid Columns="1"/>
</ItemsPanelTemplate>
</ListView.ItemsPanel>
<ListView.ItemTemplate>
<!--no changes-->
</ListView.ItemTemplate>
</ListView>
there can be a issue when ListView doesn't have enough height for all elements. In that case I would put ListView into ViewBox
Set HorizontalContentAlignment to Stretch for items.
<ListView>
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
</Style>
</ListView.ItemContainerStyle>
</ListView>

align wpf tabcontrol strip

I'm trying to align a tabcontrol strip on the right.
Just to be clear - I want the tabs on the top (tabstripplacement), but aligned on the right.
The Headers for the TabItem's are located in a panel of type TabPanel. We can add HorizontalAlignment="Right" for it in the Resources of TabControl
<TabControl ...>
<TabControl.Resources>
<Style TargetType="TabPanel">
<Setter Property="HorizontalAlignment" Value="Right"/>
</Style>
</TabControl.Resources>
<!--...-->
</TabControl>
I don’t know why, but ItemsPanel replacement doesn’t work. You must replace template for whole TabControl:
<TabControl ItemsSource="{Binding Items}">
<TabControl.Template>
<ControlTemplate TargetType="TabControl">
<DockPanel LastChildFill="True">
<StackPanel DockPanel.Dock="Top" Orientation="Horizontal" HorizontalAlignment="Right" IsItemsHost="true"/>
<ContentPresenter ContentSource="SelectedContent"/>
</DockPanel>
</ControlTemplate>
</TabControl.Template>
<!-- This XAML doesnt work!-->
<!--<TabControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel HorizontalAlignment="Right" IsItemsHost="True"/>
</ItemsPanelTemplate>
</TabControl.ItemsPanel>-->
</TabControl>

Setting Canvas properties in an ItemsControl DataTemplate

I'm trying to databind to this ItemsControl:
<ItemsControl ItemsSource="{Binding Path=Nodes, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
By using this DataTemplate, I'm trying to individually position my Node elements on the Canvas correctly:
<DataTemplate DataType="{x:Type Model:EndNode}">
<Controls:EndNodeControl Canvas.Left="{Binding Path=XPos}" Canvas.Top="{Binding Path=YPos}" />
</DataTemplate>
However, it's not working as expected. All my node elements are drawn on top of each other in the same position. Any suggestions on how to accomplish this?
The attached properties only work on direct children of the Canvas. ItemsControl will place ContentPresenter controls as its direct children, so you might want to add a style for that as well:
<ItemsControl ItemsSource="{Binding Path=Nodes}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemContainerStyle>
<Style TargetType="ContentPresenter">
<Setter Property="Canvas.Left" Value="{Binding Path=XPos}" />
<Setter Property="Canvas.Top" Value="{Binding Path=YPos}" />
</Style>
</ItemsControl.ItemContainerStyle>
</ItemsControl>

Categories

Resources