Modify ListView ItemTemplate at runtime - c#

I have a ListView:
<ListView>
<ListView.ItemTemplate>
<DataTemplate>
<Grid Height="90" HorizontalAlignment="Stretch" Background="Gray">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100"/>
<ColumnDefinition Width="1.2*"/>
<ColumnDefinition x:Name="changeThis" Width="140"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="45"/>
</Grid.ColumnDefinitions>
...
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
When the screen orientation changes to Portrait I would like the 3rd (140px wide) column to disappear, so the other columns stay properly visible. I use VisualStateManager to manage the orientation change, but I get an exception if I try to change the "changeThis" ColumnDefinition to 0. And strangely I cannot access "changeThis" ColumnDefinition from the code behind. It is a Windows Store App.

Sadly, the x:Name is local to the item template and cannot be accessed from outside.
Possible Solutions are:
1: Bind the Width to a Property.
{Binding DataContext.MyColumnWidth, ElementName=LayoutRoot}
2: Use an ItemTemplateSelector with different Templates for Orientations.

Related

Make texts look the same size in xaml

I write an XAML application and I have a problem with the size of text. How can I make the texts look complete but with the same size? (make it responsive).
This is a small example of my XAML code:
<!-- (0, 0) Availability -->
<Grid Grid.Row="0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Viewbox Stretch="Uniform">
<Grid Grid.Column="0">
<TextBlock Style="{StaticResource OeeText}">Disponibilidad</TextBlock>
</Grid>
</Viewbox>
<Grid Grid.Column="1">
<TextBlock Style="{StaticResource OeeValues}">100%</TextBlock>
</Grid>
</Grid>
In the Window App, the text shows as:
How can I make all three texts look the same size?
Thanks )
You may define the size of a textBox in a responsive manner using the ViewBox Component but you have to use it inside the grid , in order to wrap the textBox Control
<Viewbox Stretch="Uniform" MaxWidth="200" MaxHeight="200" MinWidth="100" MinHeight="100">
<TextBox x:Name="MyTextBox" />
</Viewbox>
You may also control the size by setting its max/min of width and height as mentioned in the docs

Listbox looks different in xaml viewer than in the program window

I'm working on a WPF Application, and i encountered the following problem,
ignored it until now though.
I want to display a Listbox and a Label on top of it.
For that I have the following XAML code:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Label Grid.Column="1" Content="Packs" Margin="60, 65, 60, 0"/>
<ListBox Grid.Column="1" Height="200" Width="150"/>
</Grid>
This gives the following output in the design window
You can ignore the buttons on the left.
As you can see the Label is right on top of the Listbox.
Now when I open my program, the window makes it seem like the Listbox is on top
of the Label.
I tried a lot rearranging the XAML-Code to display it differently, but this problem stay the same, and although I could bypass it by using values that are simply too big for the designer, it still bugs me that I can't find a solution.
Also please keep in mind that my program will not be resizeable, so dont worry about that.
Thank you for your answers!
You can put Label and ListBox in another Panel (StackPanel) and align that Panel in outer Grid:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="1"
Width="150"
VerticalAlignment="Center"
HorizontalAlignment="Center">
<Label Content="Packs"/>
<ListBox Height="200"/>
</StackPanel>
</Grid>
this way both elements will be in the center of middle column even if window is resized.

WPF Grid Column width in DataTemplate does not work

I have DataWindow and UserControls (different ViewModels).
My DataWindow.Xaml:
<catel:DataWindow.Resources>
<DataTemplate DataType="{x:Type viewmodels:MessageViewModel}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="20*"/>
<ColumnDefinition Width="80*"/>
</Grid.ColumnDefinitions>
<Views:MessageView Grid.Column="1"/>
</Grid>
</DataTemplate>
</catel:DataWindow.Resources>
<ItemsControl ItemsSource="{Binding Messages}">
My UserControl: MessageView.Xaml
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Border Grid.Row="0" Background="Red">
</Border>
<Border Grid.Row="1">
...
Content
...
</Border>
</Grid>
Messages : ObservableCollection<ViewModelBase>();
My content in UserControl adds to DataWindow dynamically at runtime. If content width in UserControl is more than WindowWidth ColumnWidth (column1 20* and column2 80*) does not work. I see only Grid.Column(80*) and it's width is 100*. What am I doing wrong?
Thanks for help!
It's impossible render an element 80% of windows when its size is more than windows size.
for solving this problem you can make windows size dynamic by removing Windows Width attribute in your code.

Bind Width property of elements which are horizontally stretched

I have a group box and grid splitter control in a column of the grid. Horizontal Alignment of group box is set to stretch so it occupies all the space when I drag the splitter. All works well.
Now I need to store the value of the group box in a property of the bound object but as soon as I bind the width property it gets stuck it is no longer stretching itself upon stretching the splitter.
I know the reason because now the binded property is responsible for its width and it is not getting changed. But don't know how to make it work. This is my XAML.
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid x:Name="InnerGrid" HorizontalAlignment="Stretch" Height="{Binding ElementName=Control1,Path=ActualHeight}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" MinWidth="200"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<GroupBox Header="{Binding TrackName}" VerticalAlignment="Stretch" Margin="3 0 3 0" HorizontalAlignment="Stretch" />
<GridSplitter Width="5" VerticalAlignment="Stretch" Focusable="False" Background="Gray"/>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
Perhaps you're actually interested in binding the ColumnDefinition width, as so:
<Grid.ColumnDefinitions>
<ColumnDefinition Width="{Binding Width}" MinWidth="200"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
As I understand you need read calculated width of the GroupBox. You can use ActualWidth property for this purpose.
Edit:
You can write custom GroupBox and make use of Dependency Properties:
public class MyGroupBox : GroupBox
{
public static readonly DependencyProperty CurrentWidthProperty =
DependencyProperty.Register("CurrentWidth", typeof(double),
typeof(MyGroupBox), new FrameworkPropertyMetadata(0d));
public double CurrentWidth
{
get { return this.ActualWidth; }
set { SetValue(CurrentWidthProperty, value); }
}
}
XAML:
<Window x:Class="FunWithWpfAndXP.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:FunWithWp"
Title="Window1" Height="300" Width="300">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" MinWidth="200"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<local:MyGroupBox CurrentWidth="{Binding Path=myProp}" VerticalAlignment="Stretch" Margin="3 0 3 0" HorizontalAlignment="Stretch"/>
<GridSplitter Width="5" VerticalAlignment="Stretch" Focusable="False" Background="Gray"/>
</Grid>
</Window>
The problem is that your binding is resetting the width changed by the GridSplitter, setting the Mode of the GroupBox Width binding to OneWayToSource should (probably) help you, you'll probably get something like this:
<GroupBox Width="{Binding Path=MyGroupBoxWidth, Mode=OneWayToSource}"/>
MSDN:
OneWayToSource: Updates the source property when the target property changes.
Setting this will cause that the property in your code will be updated but not the other way around

Graphical object alignment

I'm trying to do something very simple in Xaml but can't find the solution.
Would like to have 3 columns set this way:
Left column: contains an combobox that I want to be aligned on the left
Middle column: Contains a text from time to time. When displayed, want it to be centered in the remaining space.
Right column: Contains some Wrapping panel that I want aligned to the right.
So far I've done this:
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
The Middle column Xaml is:
<WrapPanel Grid.Column="1">
<TextBlock Name="UserInfoLogs" Text="{Binding Path=...}" />
</WrapPanel>
It aligns correctly the left and right columns' elements, but when displaying the centered text it is naturally aligned to the left of the middle column.
thanks!
You've got it, you're just missing one ingredient;
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<TextBlock Text="Left"/>
<!-- Most of the time just setting the HorizontalAlignment will suffice,
except when the TextBlock object is for whatever reason allowed to
stretch further than its contents. In which case TextAlignment will
align the Text within the Center of itself. -->
<TextBlock Grid.Column="1" Text="Center"
HorizontalAlignment="Center" TextAlignment="Center"/>
<TextBlock Grid.Column="2" Text="Right"/>
</Grid>
Hope this helps.

Categories

Resources