Textblocks overlapping each other in XAML - c#

This is what I am trying to obtain:
Name
Date
This is the XAML I have. But in the result, both the texts Name & Date are overlapping each other.
<DataTemplate>
<Grid x:Name="showGrid">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<StackPanel>
<Grid Height="{Binding widthMA}" Width="{Binding widthMA}">
<Grid Margin="3.5" Background="White">
<Grid VerticalAlignment="Bottom" Background="Black" Height="30">
<TextBlock Text="{Binding strName}" Style="{StaticResource AlbumTitleText}" Grid.Row="0" />
<TextBlock Text="{Binding dateCreated}" Style="{StaticResource ArtistTitleText}" Grid.Row="1" />
</Grid>
</Grid>
</Grid>
</StackPanel>
</Grid>
</DataTemplate>
And the styles AlbumTitleText and ArtistTitleText are here
<Style x:Key="AlbumTitleText" TargetType="TextBlock">
<Setter Property="Foreground" Value="White" />
<Setter Property="HorizontalAlignment" Value="Left" />
<Setter Property="FontSize" Value="18" />
<Setter Property="FontFamily" Value="Fonts/Gotham-Bold.ttf#Gotham Bold" />
<Setter Property="TextTrimming" Value="CharacterEllipsis" />
<Setter Property="FontWeight" Value="Bold" />
<Setter Property="Margin" Value="10,-2,10,7"></Setter>
</Style>
<Style x:Key="ArtistTitleText" TargetType="TextBlock">
<Setter Property="Foreground" Value="White" />
<Setter Property="HorizontalAlignment" Value="Left" />
<Setter Property="FontSize" Value="16" />
<Setter Property="FontFamily" Value="Fonts/Gotham-Bold.ttf#Gotham Bold" />
<Setter Property="TextTrimming" Value="CharacterEllipsis" />
<Setter Property="FontWeight" Value="Normal" />
<Setter Property="Margin" Value="10,7,10,0"></Setter>
</Style>

I think your row definitions are in the wrong place. Try ...
<DataTemplate>
<Grid x:Name="showGrid">
<StackPanel>
<Grid Height="{Binding widthMA}" Width="{Binding widthMA}">
<Grid Margin="3.5" Background="White">
<Grid VerticalAlignment="Bottom" Background="Black" Height="30">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<TextBlock Text="{Binding strName}" Style="{StaticResource AlbumTitleText}" Grid.Row="0" />
<TextBlock Text="{Binding dateCreated}" Style="{StaticResource ArtistTitleText}" Grid.Row="1" />
</Grid>
</Grid>
</Grid>
</StackPanel>
</Grid>
</DataTemplate>

Related

How to design this ListViewItem

I want my ListViewItem to look like this. As you can see when the ListViewItem is selected/has focus the Border should change color.
The Main Problem is that I can't put a Border around the ContenPresenter in the ControlTemplate because than also the TextBox with the "Description"-Binding will be inside the Border. But I only want the TextBox and Icon to be inside the Border that changes Colors and not also the Description ("Nachname", "Vorname").
This is the XAML I have so far. I don't know how to change the border in the ControlTemplate:
<ListView x:Name="SearchFields" Grid.Row="0" Grid.Column="0" ItemsSource="{Binding CustomerSearchFields}" SelectedItem="{Binding selectedSearchField, UpdateSourceTrigger=LostFocus}" Style="{StaticResource MaterialDropShadowStyle}"
BorderThickness="0,0,2,0" Padding="24,24,24,0" HorizontalContentAlignment="Stretch" helper:EnterKeyTraversal.IsEnabled="True" KeyboardNavigation.TabNavigation="Cycle" FontFamily="{StaticResource DefaultFontFamily}"
Background="{StaticResource ColorLightGray2}">
<ListView.Resources>
<DataTemplate DataType="{x:Type model:CustomerSeachFieldViewModel}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="48" />
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" Text="{Binding Description}" FontSize="{StaticResource FontSizeSmall}" FontWeight="SemiBold" Foreground="{StaticResource ColorDarkGray}" Margin="0,0,0,4" />
<Border x:Name="PART_Border" Grid.Row="1" BorderThickness="1" BorderBrush="{StaticResource ColorGray}">
<Grid Background="White">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="48" />
</Grid.ColumnDefinitions>
<TextBox Grid.Column="0" Text="{Binding SearchText}" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" FontSize="{StaticResource FontSizeNormal}" Padding="12,15" BorderThickness="0" />
<Border Grid.Column="1" Background="{StaticResource ColorLightGray2}" Margin="8">
<ctrl:IconViewbox IconData="{StaticResource IconPathSearch}" IconSize="16" IsTabStop="False" />
</Border>
</Grid>
</Border>
</Grid>
</DataTemplate>
</ListView.Resources>
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="IsTabStop" Value="False" />
<Setter Property="Margin" Value="0,0,0,24" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<ContentPresenter Content="{Binding}" />
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsKeyboardFocusWithin" Value="True">
<Setter Property="IsSelected" Value="True" />
</Trigger>
<Trigger Property="IsSelected" Value="True">
<Trigger.Setters>
<Setter Property="BorderBrush" Value="Fuchsia" />
</Trigger.Setters>
</Trigger>
</Style.Triggers>
</Style>
</ListView.ItemContainerStyle>
</ListView>
You can add a Trigger to your Border named PART_Border as follow:
<Border x:Name="PART_Border" Grid.Row="1" BorderThickness="1" >
<Border.Style>
<Style TargetType="Border">
<Setter Property="BorderBrush" Value="DarkGray" />
<Style.Triggers>
<DataTrigger Binding="{Binding IsSelected, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ListViewItem}}}"
Value="True" >
<Setter Property="BorderBrush" Value="Black"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Border.Style>
<Grid Background="White">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="48" />
</Grid.ColumnDefinitions>
<TextBox Grid.Column="0"
Text="{Binding SearchText}" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" FontSize="15" Padding="12,15" BorderThickness="0" />
<Border Grid.Column="1" Background="Gray" Margin="8">
<Rectangle Width="20" Height="20" />
</Border>
</Grid>
</Border>
Please note that I replaced some StaticResource mapped to some Colors from your code with standard color in order to test my code.
I also replaced the icon with a Rectangle for the same reason.
Try for your IsSelected trigger:
<Trigger Property="IsSelected" Value="True">
<Setter TargetName="PART_Border" Property="BorderBrush" Value="Fuchsia" />
<Setter TargetName="PART_Border" Property="BorderThickness" Value="1" />
</Trigger>
You could add a Style with a DataTrigger that binds to the IsSelected property of the parent ListViewItem to the Border in your DataTemplate:
<Border x:Name="PART_Border" Grid.Row="1" BorderThickness="1">
<Border.Style>
<Style TargetType="Border">
<Setter Property="BorderBrush" Value="{StaticResource ColorGray}" />
<Style.Triggers>
<DataTrigger Binding="{Binding IsSelected, RelativeSource={RelativeSource AncestorType=ListViewItem}}"
Value="True">
<Setter Property="BorderBrush" Value="Red" />
</DataTrigger>
</Style.Triggers>
</Style>
</Border.Style>
</Border>
Note that you need to set the default value of the property ({StaticResource ColorGray}) using a Style setter for the DataTrigger to be able to set the property when the ListViewItem is selected.

How do i split Grid to make only some of the elements scrollable?

This is not actually WPF, but Avalonia, but they are almost identical, so i figured i will ask the question in both categories. I have an issue here. This window contains Grid that has "Name" and "Description" buttons at the top, some items in 2 StackPanels below them and a GridSplitter separating them both. My question is, how do i make only the bottom items scrollable? If i surround my Grid with ScrollViewer, it will scroll all Grid including "Name" and "Description" buttons at the top, and i want to scroll only bottom elements (represented by 3 StackPanels in my code). Also, elements at the left and at the right should both be scrolled simultaneously. The confusing thing is, i can't even put all my elements as children of ScrollViewer, because it can only have one element as a child. And i can't surround my 3 StackPanels with some Panel because i won't be able to put them in different cells of the Grid anymore.
<UserControl
x:Class="GUI.Windows.MainWindow.Elements.TaskList"
xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
d:DesignHeight="450"
d:DesignWidth="800"
mc:Ignorable="d">
<UserControl.Styles>
<Style Selector="Button.title">
<Setter Property="Margin" Value="-1" />
<Setter Property="BorderBrush" Value="Gray" />
<Setter Property="BorderThickness" Value="2" />
<Setter Property="Height" Value="40" />
<Setter Property="FontSize" Value="15" />
<Setter Property="Background" Value="LightCyan" />
</Style>
<Style Selector="Border.element">
<Setter Property="Margin" Value="-1" />
<Setter Property="BorderBrush" Value="LightGray" />
<Setter Property="BorderThickness" Value="2" />
<Setter Property="CornerRadius" Value="3" />
<Setter Property="Height" Value="50" />
<Setter Property="Background" Value="#f0f0f0" />
</Style>
<Style Selector="Button.element">
<Setter Property="Height" Value="50" />
<Setter Property="Background" Value="Transparent" />
<Setter Property="BorderThickness" Value="0" />
</Style>
<Style Selector="TextBlock.element">
<Setter Property="FontSize" Value="25" />
</Style>
</UserControl.Styles>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="1" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="40" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Button
Grid.Row="0"
Grid.Column="0"
Classes="title">
Name
</Button>
<Button
Grid.Row="0"
Grid.Column="2"
Classes="title">
Description
</Button>
<GridSplitter
Grid.Row="0"
Grid.RowSpan="2"
Grid.Column="1"
Width="10"
VerticalAlignment="Stretch"
ZIndex="2" />
<StackPanel
Grid.Row="1"
Grid.ColumnSpan="3"
ZIndex="1">
<ItemsControl Items="{Binding Tasks}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Button Classes="element" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>
<StackPanel Grid.Row="1" Grid.Column="0">
<ItemsControl Items="{Binding Tasks}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Border Classes="element">
<TextBlock Classes="element" Text="{Binding Name}" />
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>
<StackPanel Grid.Row="1" Grid.Column="2">
<ItemsControl Items="{Binding Tasks}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Border Classes="element">
<TextBlock Classes="element" Text="{Binding Description}" />
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>
</Grid>
You need a customized ScrollViewer content template with column headers outside of the scrolleble area. You can copy-paste the default one and wrap ScrollContentPresenter https://github.com/AvaloniaUI/Avalonia/blob/master/src/Avalonia.Themes.Default/ScrollViewer.xaml#L7
Column headers need to use SharedSizeGroup to make them the same width as content cells.

Xamarin forms align each texts on their baselines

This is what I am currently having on screen with my texts:
Is there a way to align the 152 and bar? Also the same with..
15 MinutesRemaining and x?
Here is my current code:
<Grid>
<Frame Style="{StaticResource FrameStyle}">
<Grid Style="{StaticResource TellyGridStyle}">
<Frame Grid.Column="0" BackgroundColor="Green" Margin="0,10,10,10" Padding="20">
<Label Text="1" Style="{StaticResource TeamLabelStyle}" />
</Frame>
<Grid Grid.Column="1" Style="{StaticResource AutoGridStyle}">
<Grid Grid.Column="0" Grid.Row="0" Style="{StaticResource EvacuationGridStyle}">
<Label TextColor="Green" Text="152" FontSize="72" VerticalTextAlignment="End" />
<Label Grid.Column="1" VerticalTextAlignment="End" Text="bar" TextColor="Blue" FontSize="54" />
</Grid>
<Grid Grid.Column="1" Grid.Row="0" Style="{StaticResource EvacuationGridStyle}">
<Label Grid.Row="0" TextColor="Lime" IsVisible="false" Text="Low Pressure Warning" FontSize="40" />
<Label Grid.Row="1" Text="Evacuation Confirmed" IsVisible="false" FontSize="33" Style="{StaticResource LabelStyle}" />
</Grid>
<BoxView Grid.Row="1" Grid.ColumnSpan="4" HeightRequest="20" BackgroundColor="Gray" HorizontalOptions="FillAndExpand" />
<Grid Grid.Row="2" Grid.ColumnSpan="3" Style="{StaticResource RadioGridStyle}">
<Label Grid.Column="0" Text="15" FontSize="33" Style="{StaticResource LabelStyle}" />
<Label Grid.Column="1" Text="MinutesRemaining" FontSize="25" Style="{StaticResource LabelStyle}" />
<Label Grid.Column="2" Text="X" Style="{StaticResource LabelStyle}" />
</Grid>
</Grid>
<StackLayout Grid.Column="2" Style="{StaticResource VerticalStackLayoutStyle}" Padding="30,40,30,40" BackgroundColor="Red">
<Label Text="R" TextColor="{StaticResource EcbWhite}" FontSize="42" HorizontalTextAlignment="Center" Style="{StaticResource LabelStyle}" />
<Label Text="Evacuate" TextColor="{StaticResource EcbWhite}" Style="{StaticResource LabelStyle}" />
</StackLayout>
</Grid>
</Frame>
</Grid>
Static Resources:
<Style x:Key="BaseStyle" TargetType="View">
<Setter Property="Margin" Value="0" />
</Style>
<Style x:Key="StackLayoutStyle" TargetType="StackLayout" BasedOn="{StaticResource BaseStyle}">
<Setter Property="Padding" Value="0" />
<Setter Property="Spacing" Value="0" />
</Style>
<Style x:Key="HorizontalStackLayoutStyle" TargetType="StackLayout" BasedOn="{StaticResource StackLayoutStyle}">
<Setter Property="Orientation" Value="Horizontal" />
<Setter Property="HorizontalOptions" Value="Start" />
<!-- <Setter Property="Spacing" Value="10" />-->
</Style>
<Style x:Key="VerticalStackLayoutStyle" TargetType="StackLayout" BasedOn="{StaticResource StackLayoutStyle}">
<Setter Property="Orientation" Value="Vertical" />
<Setter Property="VerticalOptions" Value="CenterAndExpand" />
</Style>
<Style x:Key="GridStyle" TargetType="Grid" BasedOn="{StaticResource BaseStyle}">
<Setter Property="Padding" Value="0" />
<Setter Property="RowSpacing" Value="0" />
<Setter Property="ColumnSpacing" Value="5" />
</Style>
<Style x:Key="FrameStyle" TargetType="Frame" BasedOn="{StaticResource BaseStyle}">
<Setter Property="Padding" Value="0" />
<Setter Property="HorizontalOptions" Value="FillAndExpand" />
<Setter Property="VerticalOptions" Value="FillAndExpand" />
<Setter Property="BackgroundColor" Value="{DynamicResource themeColor}" />
</Style>
<Style x:Key="LabelStyle" TargetType="Label">
<Setter Property="VerticalTextAlignment" Value="End" />
<Setter Property="TextColor" Value="Black" />
</Style>
<Style x:Key="TeamLabelStyle" TargetType="Label">
<Setter Property="FontSize" Value="24" />
<Setter Property="VerticalOptions" Value="Center" />
<Setter Property="VerticalTextAlignment" Value="End" />
<Setter Property="TextColor" Value="{StaticResource MsaWhite}" />
</Style>
<!--<ColumnDefinitionCollection x:Key="AutoColumns">
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</ColumnDefinitionCollection>-->
<RowDefinitionCollection x:Key="AutoRows">
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</RowDefinitionCollection>
<Style x:Key="TellyGridStyle" TargetType="Grid" BasedOn="{StaticResource GridStyle}">
<Setter Property="RowDefinitions" Value="{StaticResource AutoRows}">
<Setter.Value>
<RowDefinitionCollection>
<RowDefinition Height="Auto" />
</RowDefinitionCollection>
</Setter.Value>
</Setter>
<Setter Property="ColumnDefinitions">
<Setter.Value>
<ColumnDefinitionCollection>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</ColumnDefinitionCollection>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="AutoGridStyle" TargetType="Grid" BasedOn="{StaticResource GridStyle}">
<Setter Property="RowDefinitions">
<Setter.Value>
<RowDefinitionCollection>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</RowDefinitionCollection>
</Setter.Value>
</Setter>
<Setter Property="ColumnDefinitions">
<Setter.Value>
<ColumnDefinitionCollection>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</ColumnDefinitionCollection>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="EvacuationGridStyle" TargetType="Grid" BasedOn="{StaticResource GridStyle}">
<Setter Property="RowDefinitions">
<Setter.Value>
<RowDefinitionCollection>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto"/>
</RowDefinitionCollection>
</Setter.Value>
</Setter>
<Setter Property="ColumnDefinitions">
<Setter.Value>
<ColumnDefinitionCollection>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto"/>
</ColumnDefinitionCollection>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="RadioGridStyle" TargetType="Grid" BasedOn="{StaticResource GridStyle}">
<Setter Property="RowDefinitions">
<Setter.Value>
<RowDefinitionCollection>
<RowDefinition Height="Auto" />
</RowDefinitionCollection>
</Setter.Value>
</Setter>
<Setter Property="ColumnDefinitions">
<Setter.Value>
<ColumnDefinitionCollection>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</ColumnDefinitionCollection>
</Setter.Value>
</Setter>
</Style>
Thanks in Advance!
To avoid the issue that each of your labels vertical (Y / height) size is different due to the fact that different size fonts are being used and to avoid hard-coding the height of those labels, you can combine those labels into one by using FormattedString.
This way, you have one label who's height is calculated by the tallest element (i.e. font) and thus when using YAlign="End" VerticalTextAlignment="End" your text is bottom aligned.
<Grid Grid.Column="0" Grid.Row="0" Style="{StaticResource EvacuationGridStyle}">
<Label YAlign="End" VerticalTextAlignment="End">
<Label.FormattedText>
<FormattedString>
<Span Text="152" TextColor="Green" FontSize="72" />
<Span Text="bar" TextColor="Blue" FontSize="54" />
</FormattedString>
</Label.FormattedText>
</Label>
</Grid>
Note: If you need to change the discrete elements of the FormattedString just as if they were separate labels, you can assign x:Name, BindingContext, Binding as a Span is a bindable object.
<Span x:Name="barValue" BindingContext="aContext" Text="{Binding BarValue}" TextColor="Green" FontSize="72" />

Making GridSplitter working across rows

I'm trying to get the GridSplitter to work across the rows in my grid:
However, the RowSpan property doesn't seem to work in case of this control.
How can I get the GridSplitter to work across my grid table and share the column width when moved?
This is my code:
<StackPanel>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid Grid.Row="0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width=".3*" MinWidth="100" />
<ColumnDefinition Width="2" />
<ColumnDefinition Width="*" MinWidth="400" />
</Grid.ColumnDefinitions>
<Grid.Resources>
<Style TargetType="TextBlock">
<Setter Property="Padding" Value="3" />
<Setter Property="Foreground" Value="Silver" />
<Setter Property="FontWeight" Value="Bold" />
<Setter Property="HorizontalAlignment" Value="Center" />
</Style>
<Style TargetType="Border">
<Setter Property="BorderThickness" Value="1" />
<Setter Property="BorderBrush" Value="Silver" />
<Setter Property="Background" Value="Black" />
</Style>
</Grid.Resources>
<Border Grid.Column="0">
<TextBlock Text="First Column" />
</Border>
<GridSplitter
Grid.RowSpan="1"
Grid.Column="1"
HorizontalAlignment="Stretch"
ShowsPreview="True" />
<Border Grid.Column="2">
<TextBlock Text="Second Column" />
</Border>
</Grid>
<Grid
Grid.Row="1"
Height="400"
Background="Silver">
<Grid.ColumnDefinitions>
<ColumnDefinition Width=".3*" MinWidth="100" />
<ColumnDefinition Width="*" MinWidth="400" />
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0">
<TextBlock
FontSize="30"
Foreground="Red"
Text="First Column Content" />
</StackPanel>
<StackPanel Grid.Column="1">
<TextBlock
FontSize="30"
Foreground="red"
Text="Second Column Content" />
</StackPanel>
</Grid>
</Grid>
</StackPanel>
You only have GridSplitter in the first Gird. You could merge the two grids you have into one grid to get the desired result. Here is merged XAML for you to try:
<Grid.Resources>
<Style TargetType="TextBlock">
<Setter Property="Padding" Value="3" />
<Setter Property="Foreground" Value="Silver" />
<Setter Property="FontWeight" Value="Bold" />
<Setter Property="HorizontalAlignment" Value="Center" />
</Style>
<Style TargetType="Border">
<Setter Property="BorderThickness" Value="1" />
<Setter Property="BorderBrush" Value="Silver" />
<Setter Property="Background" Value="Black" />
</Style>
</Grid.Resources>
<StackPanel Grid.Column="0">
<Border>
<TextBlock Text="First Column" />
</Border>
<TextBlock FontSize="30"
Foreground="Red"
Text="First Column Content" />
</StackPanel>
<GridSplitter Grid.Row="0"
Grid.Column="1"
HorizontalAlignment="Stretch"
ShowsPreview="True"
Background="Gray"/>
<StackPanel Grid.Column="2">
<Border>
<TextBlock Text="Second Column" />
</Border>
<TextBlock FontSize="30"
Foreground="red"
Text="Second Column Content" />
</StackPanel>
Also, here is the screenshot of resulting output:
You may also want to refer to this how-to page on MSDN.

SelectedRow of datagrid is not selected again after returning to same Page

I have two different Pages called Select and Edit. Both of them shares same ViewModel named SalesAccountsViewModel.
I have a DataGrid in Select Page as follows:
Then I select it any Item from the DataGrid :
Then I click on edit button on selected row as shown below:
After that I am redirected to another Page as shown below:
When I click on save button:
I am again redirected to the Previous Page but can you see the first row? It is not Highlighted fully:
Here is Select Page that I use:
<Page x:Class="MiniAccountWPF.Views.Pages.Masters.SalesAccounts.Select"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:vm="clr-namespace:MiniAccountWPF.ViewModels.Masters"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300"
Title="Select" DataContext="{StaticResource salesAccountsViewModel}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Button Grid.Row="0" Margin="0,10" HorizontalAlignment="Left"
Content="{Binding SelectedChildMenuItem.MenuItemName, Converter={StaticResource createButtonContentConverter}, Source={StaticResource mainWindowViewModel}}" />
<DataGrid Grid.Row="1" ItemsSource="{Binding Ledgers}" SelectedValue="{Binding SelectedLedger}"
IsReadOnly="True" AutoGenerateColumns="False" SelectionMode="Single" SelectionUnit="FullRow">
<DataGrid.Columns>
<DataGridTextColumn Header="Customer Name" Binding="{Binding LedgerName}" />
<DataGridTextColumn Header="City" Binding="{Binding City}" />
<DataGridTemplateColumn Header="Mobile Numbers">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock>
<Run Text="{Binding MobileNo1, Converter={StaticResource mobileNumberFormatConverter}, ConverterParameter=N}" />
<Run Text="{Binding MobileNo1, Converter={StaticResource mobileNumberFormatConverter}, ConverterParameter=S}" FontFamily="Consolas"/>
<Run Text=" " FontFamily="Consolas"/>
<Run Text="{Binding MobileNo2, Converter={StaticResource mobileNumberFormatConverter}, ConverterParameter=N}" />
<Run Text="{Binding MobileNo2, Converter={StaticResource mobileNumberFormatConverter}, ConverterParameter=S}" FontFamily="Consolas"/>
</TextBlock>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTextColumn Header="Opening Balance" Binding="{Binding OpeningBalance}" />
<DataGridTemplateColumn Header="Edit">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Button Content="Edit" Style="{StaticResource EditButton}"
Command="{Binding DataContext.EditCommand, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Page}}}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Header="Delete">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Button Content="Delete" Style="{StaticResource DeleteButton}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
</Grid>
</Page>
Here is the Edit Page:
<Page x:Class="MiniAccountWPF.Views.Pages.Masters.SalesAccounts.Edit"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:vm="clr-namespace:MiniAccountWPF.ViewModels.Masters"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300"
Title="Edit" DataContext="{StaticResource salesAccountsViewModel}">
<Grid DataContext="{Binding SelectedLedger}">
<Grid.RowDefinitions>
<RowDefinition Height="40" />
<RowDefinition Height="Auto" />
<RowDefinition Height="10" />
<RowDefinition Height="Auto" />
<RowDefinition Height="10" />
<RowDefinition Height="Auto" />
<RowDefinition Height="10" />
<RowDefinition Height="Auto" />
<RowDefinition Height="10" />
<RowDefinition Height="30" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="50" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="20" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="350" />
</Grid.ColumnDefinitions>
<TextBlock Grid.Row="1" Grid.Column="1" Text="Name" Style="{StaticResource txtBlock}"/>
<TextBlock Grid.Row="1" Grid.Column="1" Text=" : " HorizontalAlignment="Right" Style="{StaticResource txtBlock}"/>
<TextBox Grid.Row="1" Grid.Column="2" Grid.ColumnSpan="3" Text="{Binding LedgerName}"/>
<TextBlock Grid.Row="3" Grid.Column="1" Text="City" Style="{StaticResource txtBlock}"/>
<TextBlock Grid.Row="3" Grid.Column="1" Text=" : " HorizontalAlignment="Right" Style="{StaticResource txtBlock}"/>
<TextBox Grid.Row="3" Grid.Column="2" Text="{Binding City}"/>
<TextBlock Grid.Row="5" Grid.Column="1" Text="Mobile No." Style="{StaticResource txtBlock}"/>
<TextBlock Grid.Row="5" Grid.Column="1" Text=" : " HorizontalAlignment="Right" Style="{StaticResource txtBlock}"/>
<TextBox Grid.Row="5" Grid.Column="2" Text="{Binding MobileNo1}"/>
<TextBox Grid.Row="5" Grid.Column="4" Text="{Binding MobileNo2}"/>
<TextBlock Grid.Row="7" Grid.Column="1" Text="Opening Balance " Style="{StaticResource txtBlock}"/>
<TextBlock Grid.Row="7" Grid.Column="1" Text=" : " HorizontalAlignment="Right" Style="{StaticResource txtBlock}"/>
<TextBox Grid.Row="7" Grid.Column="2" Text="{Binding OpeningBalance}"/>
<Grid Grid.Row="10" Grid.Column="4">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="10" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Button Grid.Column="1" Content="Save"
Command="{Binding DataContext.EditSaveCommand, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Page}}}"/>
<Button Grid.Column="3" Content="Cancel" HorizontalAlignment="Left"
Command="{Binding DataContext.EditCancelCommand, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Page}}}"/>
</Grid>
</Grid>
</Page>
The ViewModel:
namespace MiniAccountWPF.ViewModels.Masters
{
public class SalesAccountsViewModel: ViewModelBase, IModule
{
public SalesAccountsViewModel()
{
SessionViewModel.Instance.ModulesOpen.Add((IModule)this);
using (MiniAccountDBEntities db = new MiniAccountDBEntities())
{
Ledgers = new ObservableCollection<Ledger>(db.Ledgers.Where(x => x.LedgerType.LedgerTypeName == "Customer"));
}
EditCommand = new RelayCommand(Edit_Click);
EditSaveCommand = new RelayCommand(Edit_Save_Click);
EditCancelCommand = new RelayCommand(Edit_Cancel_Click);
}
~SalesAccountsViewModel()
{
SessionViewModel.Instance.ModulesOpen.Remove((IModule)this);
}
private ObservableCollection<Ledger> _ledgers;
public ObservableCollection<Ledger> Ledgers
{
get
{
return _ledgers;
}
set
{
_ledgers = value;
OnPropertyChanged("Ledgers");
}
}
private Ledger _selectedLedger;
public Ledger SelectedLedger
{
get
{
return _selectedLedger;
}
set
{
_selectedLedger = value;
OnPropertyChanged("SelectedLedger");
}
}
public ICommand EditCommand { get; set; }
private void Edit_Click(object obj)
{
var mainWindowVM = SessionViewModel.GetModuleInstance("MainWindow", "MiniAccountWPF.ViewModels.MainWindowViewModel");
((MainWindowViewModel)mainWindowVM).InnerSourcePage = ((MainWindowViewModel)mainWindowVM).SelectedChildMenuItem.EditFrameNavigationURL;
}
public ICommand EditSaveCommand { get; set; }
private void Edit_Save_Click(object obj)
{
using (MiniAccountDBEntities db = new MiniAccountDBEntities())
{
Ledger ledger = db.Ledgers.Single(x => x.LedgerID == SelectedLedger.LedgerID);
ledger.LedgerName = SelectedLedger.LedgerName;
ledger.City = SelectedLedger.City;
ledger.MobileNo1 = SelectedLedger.MobileNo1;
ledger.MobileNo2 = SelectedLedger.MobileNo2;
ledger.OpeningBalance = SelectedLedger.OpeningBalance;
db.SaveChanges();
var mainWindowVM = SessionViewModel.GetModuleInstance("MainWindow", "MiniAccountWPF.ViewModels.MainWindowViewModel");
((MainWindowViewModel)mainWindowVM).InnerSourcePage = ((MainWindowViewModel)mainWindowVM).SelectedChildMenuItem.SelectFrameNavigationURL;
}
}
public ICommand EditCancelCommand { get; set; }
private void Edit_Cancel_Click(object obj)
{
var mainWindowVM = SessionViewModel.GetModuleInstance("MainWindow", "MiniAccountWPF.ViewModels.MainWindowViewModel");
((MainWindowViewModel)mainWindowVM).InnerSourcePage = ((MainWindowViewModel)mainWindowVM).SelectedChildMenuItem.SelectFrameNavigationURL;
}
public string ModuleFriendlyName
{
get { return "SalesAccountsViewModel"; }
}
public string ModuleName
{
get { return "SalesAccounts"; }
}
}
}
Styles applied to DataGrid in ResourceDictionary:
<Style TargetType="{x:Type DataGrid}">
<Setter Property="GridLinesVisibility" Value="Vertical" />
<Setter Property="RowHeaderWidth" Value="0" />
</Style>
<Style TargetType="{x:Type DataGridColumnHeader}">
<Setter Property="Background" Value="{StaticResource BrushHeaderBackground}" />
<Setter Property="Foreground" Value="White" />
<Setter Property="Padding" Value="10" />
<Setter Property="FontSize" Value="16" />
<Setter Property="FontWeight" Value="SemiBold" />
<Setter Property="HorizontalContentAlignment" Value="Center"/>
<Setter Property="BorderBrush" Value="White" />
<Setter Property="BorderThickness" Value="1,0" />
<Style.Triggers>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsMouseOver" Value="True" />
<Condition Property="CanUserSort" Value="True" />
</MultiTrigger.Conditions>
<MultiTrigger.Setters>
<Setter Property="Background" Value="{StaticResource BrushOrangeSelector}" />
</MultiTrigger.Setters>
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsPressed" Value="True" />
<Condition Property="CanUserSort" Value="True" />
</MultiTrigger.Conditions>
<MultiTrigger.Setters>
<Setter Property="Background" Value="{StaticResource BrushBlueSelector}" />
</MultiTrigger.Setters>
</MultiTrigger>
</Style.Triggers>
</Style>
<Style TargetType="{x:Type DataGridCell}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGridCell}">
<Grid Background="{TemplateBinding Background}">
<ContentPresenter VerticalAlignment="Center" HorizontalAlignment="Center" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="Background" Value="Gray" />
<Setter Property="Foreground" Value="White" />
<Setter Property="Padding" Value="10" />
<Setter Property="FontSize" Value="16" />
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Background" Value="{StaticResource BrushBlueSelector}" />
</Trigger>
</Style.Triggers>
</Style>
<Style TargetType='{x:Type DataGridRow}'>
<Setter Property="Background" Value="Gray" />
<Setter Property="HorizontalContentAlignment" Value="Center"/>
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Background" Value="{StaticResource BrushBlueSelector}" />
</Trigger>
</Style.Triggers>
</Style>
the issue was view model, which was getting created with every view, leading to multiple copies of person collection
so I did place a property for VM in ServiceLocator for single instance and initialized the same
public ListViewModel ListViewModel {get; set;}
then I replaced the declaration of view model from the list view to point to this property
DataContext="{Binding ListViewModel, Source={x:Static vm:ServiceLocator.Instance}}"
this solves the problem of multiple instance of the collection but again datagrid has some problem redoing the selection so I added a style with datatrigger to reapply the selection
<DataGrid.RowStyle>
<Style TargetType="DataGridRow">
<Style.Triggers>
<Trigger Property="IsSelected"
Value="true">
<Setter Property="Background"
Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}" />
<Setter Property="Foreground"
Value="{DynamicResource {x:Static SystemColors.HighlightTextBrushKey}}" />
</Trigger>
</Style.Triggers>
</Style>
</DataGrid.RowStyle>
this trigger will ensure the row looks selected even if the page is reloaded.
here is a working sample
EDIT
here is a solution for the issue after merging Metro.xaml
remove DataGrid.RowStyle from the DataGrid in ListView and replace the mentioned styles in Metro.xaml with these
<Style TargetType="{x:Type DataGridCell}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGridCell}">
<ContentPresenter VerticalAlignment="Center" HorizontalAlignment="Center" />
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="FontSize" Value="16" />
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Foreground" Value="Black" />
</Trigger>
</Style.Triggers>
</Style>
<Style TargetType='{x:Type DataGridRow}'>
<Setter Property="TextElement.Foreground" Value="White" />
<Setter Property="Background" Value="Gray" />
<Setter Property="Height" Value="50" />
<Setter Property="HorizontalContentAlignment" Value="Center"/>
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Background" Value="#FFE1AF4D" />
<Setter Property="TextElement.Foreground" Value="Black" />
</Trigger>
</Style.Triggers>
</Style>
It might have lost focus. I have seen similar problems where WPF controls are partially rendered.
Try putting the focus back to the target grid control.

Categories

Resources