I have a uwp desktop application with a listview in which I need to change the background color of items whose given value is empty. I've already done everything indicated by the answer to the question below, but the color doesn't change. Any help is most welcome.
uwp: how to change background color of listview item based on its value?
https://zamjad.wordpress.com/2010/01/01/applying-style-conditionally/
XAML
<Page.Resources>
<Style x:Key="SpeechLineTimingSet" TargetType="ListViewItem">
<Setter Property="Background" Value="Transparent" />
</Style>
<Style x:Key="SpeechLineTimingNotSet" TargetType="ListViewItem">
<Setter Property="Background" Value="Red" />
</Style>
<local:SpeechLineListViewStyleSelector x:Key="SpeechLineListViewStyleSelectorObject"
SpeechLineTimingSetStyle="{StaticResource SpeechLineTimingSet}"
SpeechLineTimingNotSetStyle="{StaticResource SpeechLineTimingNotSet}"/>
</Page.Resources>
<ListView x:Name="dtgSpeechLines" Grid.Column="0" Grid.Row="2" Margin="3,0,3,3"
BorderBrush="Gray" BorderThickness="1" ScrollViewer.HorizontalScrollBarVisibility="Auto"
ItemContainerStyleSelector="{StaticResource SpeechLineListViewStyleSelectorObject}"
DoubleTapped="dtgSpeechLines_DoubleTapped">
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
</Style>
</ListView.ItemContainerStyle>
<ListView.HeaderTemplate>
<DataTemplate>
<Grid Padding="12" Margin="3,5,3,5" Background="{ThemeResource SystemBaseLowColor}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="40"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="100"/>
<ColumnDefinition Width="100"/>
<ColumnDefinition Width="100"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" x:Uid="CtrPgLvwColumn0" Style="{ThemeResource CaptionTextBlockStyle}"/>
<TextBlock Grid.Column="1" x:Uid="CtrPgLvwColumn1" Style="{ThemeResource CaptionTextBlockStyle}"/>
<TextBlock Grid.Column="2" x:Uid="CtrPgLvwColumn2" Style="{ThemeResource CaptionTextBlockStyle}"/>
<TextBlock Grid.Column="3" x:Uid="CtrPgLvwColumn3" Style="{ThemeResource CaptionTextBlockStyle}"/>
<TextBlock Grid.Column="4" x:Uid="CtrPgLvwColumn4" Style="{ThemeResource CaptionTextBlockStyle}"/>
<TextBlock Grid.Column="5" x:Uid="CtrPgLvwColumn5" Style="{ThemeResource CaptionTextBlockStyle}"/>
</Grid>
</DataTemplate>
</ListView.HeaderTemplate>
<ListView.ItemTemplate>
<DataTemplate>
<Grid Margin="3,5,3,5" >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="40"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="100"/>
<ColumnDefinition Width="100"/>
<ColumnDefinition Width="100"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" TextWrapping="Wrap" FontSize="12" Text="{Binding Number}" />
<TextBlock Grid.Column="1" TextWrapping="Wrap" FontSize="12" Text="{Binding OriginalText}"/>
<TextBlock Grid.Column="2" TextWrapping="Wrap" FontSize="12" Text="{Binding TextForAudio}"/>
<TextBlock Grid.Column="3" TextWrapping="Wrap" FontSize="12" Text="{Binding SubtitleNumber}"/>
<TextBlock Grid.Column="4" TextWrapping="Wrap" FontSize="12" Text="{Binding Start}"/>
<TextBlock Grid.Column="5" TextWrapping="Wrap" FontSize="12" Text="{Binding Length}" />
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
CODE BEHIND
public class SpeechLineListViewStyleSelector : StyleSelector
{
public Style SpeechLineTimingSetStyle { get; set; }
public Style SpeechLineTimingNotSetStyle { get; set; }
protected override Style SelectStyleCore(object item, DependencyObject container)
{
SpeechLine speechLine = item as SpeechLine;
if (speechLine != null)
{
if (speechLine.Start == "")
{
return SpeechLineTimingNotSetStyle;
}
else
{
return SpeechLineTimingSetStyle;
}
}
return base.SelectStyleCore(item, container);
}
}
Please remove the ListView.ItemContainerStyle that you defined in the ListView. It overrides the style that you defined in the StyleSelector. Just put the HorizontalContentAlignment setting in the styles in the SpeechLineListViewStyleSelector.
Like:
<Style x:Key="SpeechLineTimingSet" TargetType="ListViewItem">
<Setter Property="Background" Value="Transparent" />
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
</Style>
<Style x:Key="SpeechLineTimingNotSet" TargetType="ListViewItem">
<Setter Property="Background" Value="Red" />
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
</Style>
And:
I have ListBox with DataTemplate, like this:
<ListBox ItemsSource="{Binding}" BorderBrush="Transparent"
Grid.IsSharedSizeScope="True"
HorizontalContentAlignment="Stretch"
Grid.Row="1"
Grid.Column="0" Grid.ColumnSpan="4"
Name="playerList">
<ListBox.ItemTemplate>
<DataTemplate>
<Border BorderBrush="Black" BorderThickness="2">
<Grid Margin="4">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="3*" />
<ColumnDefinition Width="3*" />
<ColumnDefinition Width="3*" />
<ColumnDefinition Width="3*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding Name}" FontWeight="Bold" FontSize="16" />
<TextBlock Grid.Column="1" Text="{Binding Drinked }" FontWeight="Bold" FontSize="16" />
<TextBlock Grid.Column="2" Text="{Binding Remaining }" FontWeight="Bold" FontSize="16" />
<Button Grid.Column="3" Name="addButton" Click="addButton_Click" FontWeight="Bold" FontSize="16">+</Button>
<Button Grid.Column="4" Name="substractButton" Click="substractButton_Click" FontSize="16">-</Button>
</Grid>
</Border>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
I have class that has the properties Name, Drinked, etc. It's in List<> that is set as DataSource. This part works fine.
But I need to add extra entry to this ListBox, that will be displayed before the DataTemplate. It will not have bindings or the same structure - it will serve as header and will have different layout than the DataTemplate.
Is there any way to do it? If I add it like in a normal ListBox, I then got an error that the ListBox must be empty before using binding.
Now the ListBox looks like this:
But I need to make it looks like this:
Is it possible to do so? If there is way to do it using other element than ListBox, I'm fine with it, as long as I can use Binding and DataTemplate.
If scrollign doesn't matter to you can put simply a static border just above your listbox..
For the scenario where you want to include that extra row in the scrolling you have to modify ListBox's template. Here is an example of an implicit style that would add a TextBlock just before your items and that would participate of the scrolling:
<Style TargetType="{x:Type ListBox}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBox}">
<ScrollViewer x:Name="ScrollViewer">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition/>
</Grid.RowDefinitions>
<TextBlock Text="I am an extra row" Grid.Row="0"/>
<ItemsPresenter Grid.Row="1"/>
</Grid>
</ScrollViewer>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
In fact by overriding the control's template you can give it all the customizations that you need... You can change the textblock for whatever any other control you want..
You could achieve this goal by using a Stackpanel or Grid. However, if you insist on using an extra row in your ListBox, you can make use of a Content Template Selector. In the following solution, I did use a trigger to set the template of the current item according to its type.
<Window.Resources>
<local:ObjectToTypeConverter x:Key="ObjectToTypeConverter" />
<ControlTemplate x:Key="emptyRow">
<Grid HorizontalAlignment="Stretch">
<Border Height="50" BorderBrush="Black" BorderThickness="2">
<TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" Text="Extra row that is not part of the binding or DataTemplate" />
</Border>
</Grid>
</ControlTemplate>
<ControlTemplate x:Key="default">
<Border BorderBrush="Black" BorderThickness="2">
<Grid Margin="4">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="3*" />
<ColumnDefinition Width="3*" />
<ColumnDefinition Width="3*" />
<ColumnDefinition Width="3*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding Name}" FontWeight="Bold" FontSize="16" />
<TextBlock Grid.Column="1" Text="{Binding Drinked }" FontWeight="Bold" FontSize="16" />
<TextBlock Grid.Column="2" Text="{Binding Remaining }" FontWeight="Bold" FontSize="16" />
<Button Grid.Column="3" Name="addButton" Click="addButton_Click" FontWeight="Bold" FontSize="16">+</Button>
<Button Grid.Column="4" Name="substractButton" Click="substractButton_Click" FontSize="16">-</Button>
</Grid>
</Border>
</ControlTemplate>
<Style x:Key="ItemStyle" TargetType="{x:Type ListBoxItem}">
<Setter Property="Template" Value="{DynamicResource emptyRow}" />
<Style.Triggers>
<DataTrigger Binding="{Binding ., Converter={StaticResource ObjectToTypeConverter}}" Value="{x:Type local:Model}">
<Setter Property="Template" Value="{DynamicResource default}" />
</DataTrigger>
</Style.Triggers>
</Style>
</Window.Resources>
<Grid>
<ListBox ItemsSource="{Binding}" BorderBrush="Transparent"
Grid.IsSharedSizeScope="True"
HorizontalContentAlignment="Stretch"
Grid.Row="1"
ItemContainerStyle="{StaticResource ItemStyle}"
Grid.Column="0" Grid.ColumnSpan="4"
Name="playerList" />
</Grid>
The converter simply converts the object to its type
public class ObjectToTypeConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return value?.GetType();
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
To add different objects to your collection, change the type to object or to a type according to your inheritance setup.
I'm working on small and very simple WPF application, BUT I'm having trouble with responsive stuffs, computer where I'm working at is like 22'' with full HD resolution and everything looks fine, let me post picture how it looks like this:
[![enter image description here][1]][1]
But when I run application on smaller monitor, my content also moves up, acctualy my datagrid and my textboxes somehow glue up to the header ( which has blue background). And it looks really bad on smaller devices. I'm working with grids and I thought that's right way, but probably I am doing something wrong..
So this is how it looks on smaller device and resolution:
[![enter image description here][2]][2]
And here is my xaml code:
<Window x:Class="Test.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525" WindowStartupLocation="CenterScreen" WindowState="Maximized" WindowStyle="None">
<!-- This is my main grid which is coming by default when I created this window -->
<Grid>
<!-- I created this grid, because soon I will put image to the left, as my logo, and few informations also, thats reason why I have column definition -->
<Grid Height="65" Margin="0" VerticalAlignment="Top">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0,60*" />
<ColumnDefinition Width="0,10*" />
<ColumnDefinition Width="0,10*" />
<ColumnDefinition Width="0,10*" />
<ColumnDefinition Width="0,10*" />
</Grid.ColumnDefinitions>
<Rectangle Grid.ColumnSpan="5">
<Rectangle.Fill>
<SolidColorBrush Color="#0091EA"></SolidColorBrush>
</Rectangle.Fill>
</Rectangle>
</Grid>
<!-- This is big grid which is separated in two columns which fits on screen 80% of screen - left part 20% of screen right part -->
<Grid Margin="0,50,0,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0,80*"/>
<ColumnDefinition Width="0,20*"/>
</Grid.ColumnDefinitions>
<Border Grid.Column="0" Grid.RowSpan="10" BorderThickness="0,0,3,0" BorderBrush="#0091EA"/>
<!-- Here are my text boxes, 6 of them, so I have 6 column definitions-->
<Grid Margin="0,0,0,0" Grid.Column="0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0,20*" />
<ColumnDefinition Width="0,30*"/>
<ColumnDefinition Width="0,12*" />
<ColumnDefinition Width="0,12*" />
<ColumnDefinition Width="0,12*" />
<ColumnDefinition Width="0,12*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="0,10*"/>
<RowDefinition Height="0,86*"/>
<RowDefinition Height="0,04*"/>
</Grid.RowDefinitions>
<Border Grid.Row="2" Grid.ColumnSpan="10" BorderThickness="0,3,0,0" BorderBrush="#0091EA"/>
<TextBox Height="40" Margin="15,0,8,0" Grid.Row="0" Grid.Column="0" TextWrapping="Wrap" Text="TextBox" Background="White" BorderBrush="#0091EA" FontSize="20" BorderThickness="1" />
<TextBox Height="40" Margin="0,0,8,0" Grid.Row="0" Grid.Column="1" TextWrapping="Wrap" Text="TextBox" Background="White" BorderBrush="#0091EA" BorderThickness="1" />
<TextBox Height="40" Margin="0,0,8,0" Grid.Row="0" Grid.Column="2" TextWrapping="Wrap" Text="TextBox" Background="White" BorderBrush="#0091EA" BorderThickness="1" />
<TextBox Height="40" Margin="0,0,8,0" Grid.Row="0" Grid.Column="3" TextWrapping="Wrap" Text="TextBox" Background="White" BorderBrush="#0091EA" BorderThickness="1" />
<TextBox Height="40" Margin="0,0,8,0" Grid.Row="0" Grid.Column="4" TextWrapping="Wrap" Text="TextBox" Background="White" BorderBrush="#0091EA" BorderThickness="1" />
<TextBox Height="40" Margin="0,0,8,0" Grid.Row="0" Grid.Column="5" TextWrapping="Wrap" Text="TextBox" Background="White" BorderBrush="#0091EA" BorderThickness="1" />
<DataGrid Grid.ColumnSpan="6" MinHeight="200" Margin="15,-20,8,50" Grid.Row="1" Grid.Column="0" AutoGenerateColumns="False" Background="White" >
<DataGrid.Resources>
<Style TargetType="{x:Type DataGridColumnHeader}">
<Setter Property="Background" Value="#0091EA"/>
<Setter Property="Opacity" Value="1"/>
<Setter Property="Foreground" Value="White"/>
<Setter Property="HorizontalContentAlignment" Value="Center" />
<Setter Property="FontSize" Value="16"/>
<Setter Property="FontFamily" Value="Arial"/>
<Setter Property="Height" Value="40"/>
</Style>
</DataGrid.Resources>
</DataGrid>
</Grid>
</Grid>
</Grid>
</Window>
Edit after Mark's answer:
XAML CODE:
<Window x:Class="xTouchPOS.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525" WindowStartupLocation="CenterScreen" WindowState="Maximized" WindowStyle="None">
<Grid>
<!-- I created this grid, because soon I will put image to the left, as my logo, and few informations also, thats reason why I have column definition -->
<Grid.RowDefinitions>
<!--Reserved header space-->
<RowDefinition Height="50" />
<!--Rest of space for textboxes and grid, etc.-->
<RowDefinition />
</Grid.RowDefinitions>
<Rectangle Fill="#0091EA" />
<!--My edit.Added one more grid to row 0 which will contain some things that I need like time, date, user which is currently using app-->
<Grid Height="50" Grid.Row="0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0,60*" />
<ColumnDefinition Width="0,10*" />
<ColumnDefinition Width="0,10*" />
<ColumnDefinition Width="0,10*" />
<ColumnDefinition Width="0,10*" />
</Grid.ColumnDefinitions>
<Image Stretch="Fill" Name="image2" Source="C:\Users\Tuca\Desktop\microsoft.logo.png" Width="135" Height="42" VerticalAlignment="Center" Margin="15,0,0,0" Grid.Column="0" HorizontalAlignment="Left"/>
<StackPanel Grid.Column="4" Orientation="Vertical" VerticalAlignment="Center" HorizontalAlignment="Center">
<TextBlock x:Name="lblTimeText" Text="Time" Margin="0,0,0,0" FontSize="15" Foreground="White" HorizontalAlignment="Left" FontFamily="Arial" VerticalAlignment="Bottom" />
<TextBlock x:Name="lblTime" Text="labelTime" Grid.Column="0" Margin="0" FontSize="18" Foreground="White" HorizontalAlignment="Left" FontFamily="Arial" />
</StackPanel>
<StackPanel Grid.Column="3" Orientation="Vertical" VerticalAlignment="Center" HorizontalAlignment="Center">
<TextBlock Name="lblDateText" Text="Date" Margin="0" FontSize="15" Foreground="White" HorizontalAlignment="Left" FontFamily="Arial" />
<TextBlock Name="lblDate" Text="labelaDate" Margin="0" FontSize="18" Foreground="White" HorizontalAlignment="Left" FontFamily="Arial" />
</StackPanel>
<StackPanel Grid.Column="2" Orientation="Vertical" VerticalAlignment="Center">
<TextBlock x:Name="lblOperater" Text="User" Margin="0,0,0,0" FontSize="15" Foreground="White" HorizontalAlignment="Left" FontFamily="Arial" VerticalAlignment="Bottom" />
<TextBlock x:Name="lblOperaterText" Text="Tony Montana" Grid.Column="0" Margin="0" FontSize="16" Foreground="White" HorizontalAlignment="Left" FontFamily="Arial" />
</StackPanel>
<StackPanel Grid.Column="1" Orientation="Vertical" VerticalAlignment="Center">
<TextBlock x:Name="lblNumber" Text="Ordinal number." Margin="0,0,40,0" FontSize="15" Foreground="White" HorizontalAlignment="Left" FontFamily="Arial" VerticalAlignment="Bottom" />
<TextBlock x:Name="lblNumber" Text="0014" Grid.Column="0" Margin="0" FontSize="16" Foreground="White" HorizontalAlignment="Left" FontFamily="Arial" />
</StackPanel>
</Grid>
<!--header section-->
<!-- This is big grid which is separated in two columns which fits on screen 80% of screen - left part 20% of screen right part -->
<Grid Margin="0,0,0,0" Grid.Row="1">
<Grid.RowDefinitions>
<!--Space for Textboxes - left to auto so that it is not overconstrained, but does
not take up too much space-->
<RowDefinition Height="Auto" />
<!--Datagrid gets the remainder of the space-->
<RowDefinition />
<!--This is the space allowed for the bottom border-->
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<!--Reserved 80% of remaining space for text/grid-->
<ColumnDefinition Width="8*"/>
<!--This is the space allowed for the right border-->
<ColumnDefinition Width="Auto" />
<!--This is the 20% of remaining space-->
<ColumnDefinition Width="2*"/>
</Grid.ColumnDefinitions>
<!--textbox section-->
<Grid Grid.Row="0" Margin="0 5">
<Grid.ColumnDefinitions>
<!--you only had 8 definitions, but 6 boxes... not sure what is intended-->
<ColumnDefinition Width="6*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBox Height="40" Margin="15,0,8,0" Grid.Row="0" Grid.Column="0" TextWrapping="Wrap" Text="TextBox" Background="White" BorderBrush="#0091EA" FontSize="20" BorderThickness="1" />
<TextBox Height="40" Margin="0,0,8,0" Grid.Row="0" Grid.Column="1" TextWrapping="Wrap" Text="TextBox" Background="White" BorderBrush="#0091EA" BorderThickness="1" />
<TextBox Height="40" Margin="0,0,8,0" Grid.Row="0" Grid.Column="2" TextWrapping="Wrap" Text="TextBox" Background="White" BorderBrush="#0091EA" BorderThickness="1" />
<TextBox Height="40" Margin="0,0,8,0" Grid.Row="0" Grid.Column="3" TextWrapping="Wrap" Text="TextBox" Background="White" BorderBrush="#0091EA" BorderThickness="1" />
<TextBox Height="40" Margin="0,0,8,0" Grid.Row="0" Grid.Column="4" TextWrapping="Wrap" Text="TextBox" Background="White" BorderBrush="#0091EA" BorderThickness="1" />
<TextBox Height="40" Margin="0,0,8,0" Grid.Row="0" Grid.Column="5" TextWrapping="Wrap" Text="TextBox" Background="White" BorderBrush="#0091EA" BorderThickness="1" />
</Grid>
<!--grid element-->
<DataGrid Grid.Row="1" MinHeight="200" Margin="15,0,8,0" AutoGenerateColumns="False" Background="White" >
<DataGrid.Resources>
<Style TargetType="{x:Type DataGridColumnHeader}">
<Setter Property="Background" Value="#0091EA"/>
<Setter Property="Opacity" Value="1"/>
<Setter Property="Foreground" Value="White"/>
<Setter Property="HorizontalContentAlignment" Value="Center" />
<Setter Property="FontSize" Value="16"/>
<Setter Property="FontFamily" Value="Arial"/>
<Setter Property="Height" Value="40"/>
</Style>
</DataGrid.Resources>
</DataGrid>
<!--right border element-->
<Rectangle Fill="#0091EA" Width="3" Grid.Column="1" Grid.RowSpan="3" />
<!--bottom border element-->
<Rectangle Fill="#0091EA" Height="3" Grid.Row="2" />
<Grid Grid.Row="0" Grid.Column="2"/>
<Grid Grid.Row="1" Grid.Column="2"/>
</Grid>
</Grid>
</Window>
So mate take a look I edited header, is that right way? To add one more grid with stackpanels, and how could I add copyright and stuffs at the bottom, shouldn't I treat it as one more row which will be very small by heigh for exaple 20px?
Thanks a lot
I think you've got the right idea - use grids for layout... You just need some more experience with it. Pikoh is correct in the comment about "hard coded" dimensions. What was a red flag for me was the negative margin on the grid (this is why it will be allowed to overlap your textboxes).
I tend to use multiple grids nested within each other to create what you're looking to do. Think of it from the largest container to the smallest. For example, there is no reason for your main grid to have 6 columns... it only needs 1 column, but 2 rows to fit your "sections". The larger section needs 3 sections side-by-side (80%/border/20%) (columns) and 2 sections in the left-most section (grid/border) Here is an example of what I think you're trying to accomplish. I left a number of the hard-coded heights and such, as I'm not privy to your requirements, but left off enough to make it responsive.
<Grid>
<!-- I created this grid, because soon I will put image to the left, as my logo, and few informations also, thats reason why I have column definition -->
<Grid.RowDefinitions>
<!--Reserved header space-->
<RowDefinition Height="40" />
<!--Rest of space for textboxes and grid, etc.-->
<RowDefinition />
</Grid.RowDefinitions>
<!--header section-->
<Rectangle Fill="#0091EA" />
<!-- This is big grid which is separated in two columns which fits on screen 80% of screen - left part 20% of screen right part -->
<Grid Margin="0,0,0,0" Grid.Row="1">
<Grid.ColumnDefinitions>
<!--Reserved 80% of remaining space for text/grid-->
<ColumnDefinition Width="8*"/>
<!--This is the space allowed for the right border-->
<ColumnDefinition Width="Auto" />
<!--This is the 20% of remaining space-->
<ColumnDefinition Width="2*"/>
</Grid.ColumnDefinitions>
<!--left-hand grid-->
<Grid>
<Grid.RowDefinitions>
<!--Space for Textboxes - left to auto so that it is not overconstrained, but does
not take up too much space-->
<RowDefinition Height="Auto" />
<!--Datagrid gets the remainder of the space-->
<RowDefinition />
<!--This is the space allowed for the bottom border-->
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<!--textbox section-->
<Grid Grid.Row="0" Margin="0 5">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="6*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBox Height="40" Margin="15,0,8,0" Grid.Row="0" Grid.Column="0" TextWrapping="Wrap" Text="TextBox" Background="White" BorderBrush="#0091EA" FontSize="20" BorderThickness="1" />
<TextBox Height="40" Margin="0,0,8,0" Grid.Row="0" Grid.Column="1" TextWrapping="Wrap" Text="TextBox" Background="White" BorderBrush="#0091EA" BorderThickness="1" />
<TextBox Height="40" Margin="0,0,8,0" Grid.Row="0" Grid.Column="2" TextWrapping="Wrap" Text="TextBox" Background="White" BorderBrush="#0091EA" BorderThickness="1" />
<TextBox Height="40" Margin="0,0,8,0" Grid.Row="0" Grid.Column="3" TextWrapping="Wrap" Text="TextBox" Background="White" BorderBrush="#0091EA" BorderThickness="1" />
<TextBox Height="40" Margin="0,0,8,0" Grid.Row="0" Grid.Column="4" TextWrapping="Wrap" Text="TextBox" Background="White" BorderBrush="#0091EA" BorderThickness="1" />
<TextBox Height="40" Margin="0,0,8,0" Grid.Row="0" Grid.Column="5" TextWrapping="Wrap" Text="TextBox" Background="White" BorderBrush="#0091EA" BorderThickness="1" />
</Grid>
<!--grid element-->
<DataGrid Grid.Row="1" MinHeight="200" Margin="15,0,8,0" AutoGenerateColumns="False" Background="White" >
<DataGrid.Resources>
<Style TargetType="{x:Type DataGridColumnHeader}">
<Setter Property="Background" Value="#0091EA"/>
<Setter Property="Opacity" Value="1"/>
<Setter Property="Foreground" Value="White"/>
<Setter Property="HorizontalContentAlignment" Value="Center" />
<Setter Property="FontSize" Value="16"/>
<Setter Property="FontFamily" Value="Arial"/>
<Setter Property="Height" Value="40"/>
</Style>
</DataGrid.Resources>
</DataGrid>
<!--bottom border element-->
<Rectangle Fill="#0091EA" Height="3" Grid.Row="2" />
</Grid>
<!--right border element-->
<Rectangle Fill="#0091EA" Width="3" Grid.Column="1" Grid.RowSpan="3" />
<!--right-hand grid-->
<Grid Grid.Column="2">
<!--Whatever content ends up here-->
</Grid>
</Grid>
</Grid>
UPDATE:
Here is the final product based on the image you included. At this point, it is just reviewing the different pieces that were used to put it together and practice that will get it to all come together for you. Subdivide into logical sections, then work within those sections when you need to manipulate the layout. If you found this helpful, please feel free to mark as answer and good luck with your application!
<!--header section-->
<Rectangle Fill="#0091EA" />
<Grid Height="50" Grid.Row="0">
<Grid.Resources>
<Style TargetType="TextBlock">
<Setter Property="Margin" Value="0" />
<Setter Property="Foreground" Value="#FFFFFFFF" />
<Setter Property="FontSize" Value="15" />
<Setter Property="FontFamily" Value="Arial" />
</Style>
<Style TargetType="StackPanel">
<Setter Property="Margin" Value="6 0" />
<Setter Property="VerticalAlignment" Value="Center" />
</Style>
</Grid.Resources>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" MinWidth="135" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="4" >
<TextBlock x:Name="lblTimeText" Text="Time" />
<TextBlock x:Name="lblTime" Text="labelTime" />
</StackPanel>
<StackPanel Grid.Column="3" >
<TextBlock Name="lblDateText" Text="Date" />
<TextBlock Name="lblDate" Text="labelaDate" />
</StackPanel>
<StackPanel Grid.Column="2" >
<TextBlock x:Name="lblOperater" Text="User" />
<TextBlock x:Name="lblOperaterText" Text="Tony Montana" />
</StackPanel>
<StackPanel Grid.Column="1" >
<TextBlock x:Name="lblBrojRacuna" Text="Ordinal number." />
<TextBlock x:Name="lblBrojRacunaText" Text="0014" FontSize="16" />
</StackPanel>
</Grid>
<!-- This is big grid which is separated in two columns which fits on screen 80% of screen - left part 20% of screen right part -->
<Grid Margin="0,0,0,0" Grid.Row="1">
<Grid.ColumnDefinitions>
<!--Reserved 80% of remaining space for text/grid-->
<ColumnDefinition Width="8*"/>
<!--This is the space allowed for the right border-->
<ColumnDefinition Width="Auto" />
<!--This is the 20% of remaining space-->
<ColumnDefinition Width="2*"/>
</Grid.ColumnDefinitions>
<!--left-hand grid-->
<Grid>
<Grid.RowDefinitions>
<!--Space for Textboxes - left to auto so that it is not overconstrained,
but does not take up too much space-->
<RowDefinition Height="Auto" />
<!--Datagrid gets the remainder of the space-->
<RowDefinition />
<!--This is the space allowed for the bottom border-->
<RowDefinition Height="Auto" />
<!--This is the space allowed for the copyright-->
<RowDefinition Height="20" />
</Grid.RowDefinitions>
<!--textbox section-->
<Grid Grid.Row="0" Margin="15 5">
<Grid.Resources>
<Style TargetType="TextBox">
<Setter Property="Height" Value="40" />
<Setter Property="Margin" Value="0 0 8 0" />
<Setter Property="TextWrapping" Value="Wrap" />
<Setter Property="BorderBrush" Value="#0091EA" />
<Setter Property="BorderThickness" Value="1" />
</Style>
</Grid.Resources>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="6*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBox Grid.Row="0" Grid.Column="0" Text="TextBox" FontSize="20" />
<TextBox Grid.Row="0" Grid.Column="1" Text="TextBox" />
<TextBox Grid.Row="0" Grid.Column="2" Text="TextBox" />
<TextBox Grid.Row="0" Grid.Column="3" Text="TextBox" />
<TextBox Grid.Row="0" Grid.Column="4" Text="TextBox" />
<TextBox Grid.Row="0" Grid.Column="5" Text="TextBox" />
</Grid>
<!--grid element-->
<DataGrid Grid.Row="1" MinHeight="200" Margin="15,0,8,0" AutoGenerateColumns="False" Background="White" >
<DataGrid.Resources>
<Style TargetType="{x:Type DataGridColumnHeader}">
<Setter Property="Background" Value="#0091EA"/>
<Setter Property="Opacity" Value="1"/>
<Setter Property="Foreground" Value="White"/>
<Setter Property="HorizontalContentAlignment" Value="Center" />
<Setter Property="FontSize" Value="16"/>
<Setter Property="FontFamily" Value="Arial"/>
<Setter Property="Height" Value="40"/>
</Style>
</DataGrid.Resources>
</DataGrid>
<!--bottom border element-->
<Rectangle Fill="#0091EA" Height="3" Grid.Row="2" />
<!--copyright-->
<TextBlock Grid.Row="3" HorizontalAlignment="Center" Text="Copyright some holder ####" />
</Grid>
<!--right border element-->
<Rectangle Fill="#0091EA" Width="3" Grid.Column="1" Grid.RowSpan="3" />
<!--right-hand grid-->
<Grid Grid.Column="2">
<!--Whatever content ends up here-->
</Grid>
</Grid>
I would advise looking into using stackpanels and dockpanels. Stackpanels have generally been more useful to me in my WPF experience. Also for headers and stuff near the top of the page use fixed spacing instead of calculated percentages based on screen size. I find it's generally better to keep menu bars at a fixed size and let the content be dynamic size.
I am currently working on a Windows Phone 8 application in which one I use the LongListSelector control.
I have created an ItemTemplate with a Grid as container and some TextBlock as children. I don't know why, but the Grid container does not match the LongListSelector control.
Here the code I use. I use a blue background for the LongListSelector control and a red one for the Grid control in order to highlight the issue :
<phone:LongListSelector
HorizontalContentAlignment="Stretch"
HorizontalAlignment="Stretch"
ItemsSource="{Binding Data}"
Background="Aqua"
>
<phone:LongListSelector.ItemTemplate>
<DataTemplate>
<Grid
HorizontalAlignment="Stretch"
Background="Red"
>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="25" />
<ColumnDefinition Width="75" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="50" />
<ColumnDefinition Width="47" />
<ColumnDefinition Width="100" />
<ColumnDefinition Width="45" />
<ColumnDefinition Width="35" />
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Style="{StaticResource LineStyle}" Text="{Binding Value}" />
<TextBlock Grid.Column="1" Style="{StaticResource LineStyle}" Text="{Binding Value}" />
<TextBlock Grid.Column="2" Style="{StaticResource LineStyle}" Text="{Binding Value}" TextAlignment="Left" TextTrimming="WordEllipsis" />
<TextBlock Grid.Column="3" Style="{StaticResource LineStyle}" Text="{Binding Value}" />
<TextBlock Grid.Column="4" Style="{StaticResource LineStyle}" Text="{Binding Value}" />
<TextBlock Grid.Column="5" Style="{StaticResource LineStyle}" Text="{Binding Value}" />
<TextBlock Grid.Column="6" Style="{StaticResource LineStyle}" Text="{Binding Value}" />
<TextBlock Grid.Column="7" Style="{StaticResource LineStyle}" Text="{Binding Value}" />
</Grid>
</DataTemplate>
</phone:LongListSelector.ItemTemplate>
</phone:LongListSelector>
And here the style :
<Style x:Key="LineStyle" TargetType="TextBlock">
<Setter Property="Foreground" Value="Black" />
<Setter Property="FontSize" Value="13" />
<Setter Property="Margin" Value="0, 12" />
<Setter Property="TextAlignment" Value="Center" />
<Setter Property="HorizontalAlignment" Value="Stretch" />
</Style>
And here a screenshot :
How to force the Grid container (the one in red) to match its parents ?
Thank you in advance for your help !
I think it is due to the vertical ScrollBar of the LongListSelector, which adds spaces in the right of the list control.
You can remove this right-spaces by adding the following piece of code in the init of your Page.
MyList.Loaded += (sender, e) =>
{
var scrollBar = ((FrameworkElement)VisualTreeHelper.GetChild(MyList, 0)).FindName("VerticalScrollBar") as ScrollBar;
scrollBar.Margin = new Thickness(-10, 0, 0, 0);
};
I made a calender using a grid. It has 7 columns, and 6 rows. By getting the day of the week and the week of the month I can figure out how to place the dates on the grid of the date choosen. However grids only show ugly grid lines. How can I change this to use a datagrid so that I can have solid gridlines like a calender should look. Or is there any other way I can get rid of the dashed grid lines to make it look better? Thanks in advance.
XAML: I make a ItemsControl and in that is the grid with the 7 columns and 6 rows.
<Grid Name="mainGrid">
<Grid Name="controlGrid" Margin="0,56,0,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="297*" />
<ColumnDefinition Width="290*" />
</Grid.ColumnDefinitions>
<ItemsControl ItemsSource="{Binding schedule}" Name="Calender" VerticalAlignment="Stretch" Grid.ColumnSpan="2">
<ItemsControl.Template>
<ControlTemplate TargetType="ItemsControl" >
<Border BorderBrush="Aqua" BorderThickness="4">
<ItemsPresenter/>
</Border>
</ControlTemplate>
</ItemsControl.Template>
<!-- ItemsPanelTemplate -->
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Grid ShowGridLines="True" Name="gridCalender">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
</Grid>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock OpacityMask="Black" Name="txtBlockdays">
<Button Content="{Binding day}" Width="175" HorizontalAlignment="Stretch" VerticalAlignment="Top" VerticalContentAlignment="Top" HorizontalContentAlignment="Left" Background="#FF94EBEB">
</Button>
</TextBlock>
</DataTemplate>
</ItemsControl.ItemTemplate>
<!-- ItemContainerStyle -->
<ItemsControl.ItemContainerStyle>
<Style >
<Setter Property="Grid.Column" Value="{Binding WeekDay}" />
<Setter Property="Grid.Row" Value="{Binding WeekNo}" />
</Style>
</ItemsControl.ItemContainerStyle>
</ItemsControl>
</Grid>
<Grid Name="dayGrid" VerticalAlignment="Top" Height="50">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Label Content="Monday" Height="Auto" HorizontalAlignment="Stretch" Margin="0" Name="label2" VerticalAlignment="Bottom" Grid.Column="1" FontSize="16" />
<Label Content="Tuesday" Height="Auto" HorizontalAlignment="Stretch" Margin="0" Name="label3" VerticalAlignment="Bottom" Grid.Column="2" FontSize="16" />
<Label Content="Wednesday" Height="Auto" HorizontalAlignment="Stretch" Name="label4" VerticalAlignment="Bottom" Grid.Column="3" Margin="0" FontSize="16" />
<Label Content="Thursday" Height="Auto" HorizontalAlignment="Stretch" Name="label5" VerticalAlignment="Bottom" Grid.Column="4" Margin="0" FontSize="16" />
<Label Content="Friday" Height="Auto" HorizontalAlignment="Stretch" Margin="0" Name="label6" VerticalAlignment="Bottom" Grid.Column="5" FontSize="16" />
<Label Content="Saturday" Height="Auto" HorizontalAlignment="Stretch" Margin="0" Name="label7" VerticalAlignment="Bottom" Grid.Column="6" FontSize="16" />
<Button Content="<" Height="23" HorizontalAlignment="Left" Margin="0,1,0,0" Name="btnDateLeft" VerticalAlignment="Top" Width="29" Click="btnDateLeft_Click" />
<Button Content=">" Height="23" HorizontalAlignment="Left" Margin="26,1,0,0" Name="btnDateRight" VerticalAlignment="Top" Width="30" Click="btnDateRight_Click" />
<Label Content="Sunday" Name="label1" Width="Auto" FontSize="16" Margin="0,19,0,0" />
</Grid>
<Label HorizontalAlignment="Left" Margin="62,1,0,0" Name="lblDate" VerticalAlignment="Top" FontSize="15" FontWeight="Bold" Height="32" />
</Grid>
Adjust your ItemContainerStyle and set ShowGridlines to false.
<ItemsControl.ItemContainerStyle>
<Style TargetType="ComboBoxItem">
<Setter Property="Grid.Column" Value="{Binding WeekDay}" />
<Setter Property="Grid.Row" Value="{Binding WeekNo}" />
<Setter Property="Control.BorderBrush" Value="Black" />
</Style>
</ItemsControl.ItemContainerStyle>
Also note that you can also place a Rectangle in each box which you cold also style accordingly. there are many ways to achieve what you are after.