This is something that I have been skipping and leaving till the end because I can't seem to find the answer and ive looked for so long.
I have a an application inside a Window, and I have built the Application to my screens resolution which is 1600 x 900. If I run the application on a screen with a resolution of 1024 x 768 my whole interface will not scale down.
Example.
Now I know alot of you will be thinking to add Dockpanels etc ... But I have tried to do this. When you change the Resolutions it doesn't work it just fixes the object to one place.
What I want to happen.
If any of you know the solution to this annoying problem, please let me know.
I dont know much about resolutions, only what I have done hours of research on.
EDIT1
Here is some of my XAML:
<DockPanel HorizontalAlignment="Left" Height="236" LastChildFill="False" Margin="380,150,0,0" VerticalAlignment="Top" Width="792">
<DataGrid x:Name="dgFake" VerticalAlignment="Center" Height="236" ItemsSource="{Binding}" Foreground="#FF474747" BorderBrush="#FFBDBDBD" HorizontalGridLinesBrush="{x:Null}" VerticalGridLinesBrush="{x:Null}" CanUserResizeRows="False" ScrollViewer.CanContentScroll="True" Background="#FFEEFAFF" RowBackground="#FFEEFAFF" RowHeaderWidth="0" RowHeight="25" AutoGenerateColumns="False" Width="792" DockPanel.Dock="Left" FontSize="16" TextBlock.TextAlignment="Center" HorizontalContentAlignment="Stretch" SelectionChanged="dgFake_SelectionChanged">
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding FFF}" Header="FFF" Visibility="Hidden" CanUserResize="False" CanUserSort="False" CanUserReorder="False" IsReadOnly="True" Width="*" />
<DataGridTextColumn Binding="{Binding EEE}" Header="EEE" CanUserResize="False" CanUserSort="False" CanUserReorder="False" IsReadOnly="True" Width="*" />
<DataGridTextColumn Binding="{Binding GGG}" Header="GGG" CanUserResize="False" CanUserSort="False" CanUserReorder="False" IsReadOnly="True" Width="*"/>
<DataGridTextColumn Binding="{Binding CCC}" Header="CCC" CanUserResize="False" CanUserSort="False" CanUserReorder="False" IsReadOnly="True" Width="*"/>
<DataGridTextColumn Binding="{Binding BBB}" Header="BBB" CanUserResize="False" CanUserSort="False" CanUserReorder="False" IsReadOnly="True" Width="*"/>
<DataGridTextColumn Binding="{Binding AAA}" Header="AAA" CanUserResize="False" CanUserSort="False" CanUserReorder="False" IsReadOnly="True" Width="*"/>
<DataGridTextColumn Binding="{Binding DDD}" Header="DDD" CanUserResize="False" CanUserSort="False" CanUserReorder="False" IsReadOnly="True" TextBlock.TextAlignment="Center" Width="*"/>
</DataGrid.Columns>
<Label x:Name="lblView" Content="Select View ..." HorizontalAlignment="Left" Margin="380,109,0,0" VerticalAlignment="Top" Foreground="#FF474747"/>
<ComboBox x:Name="cmbViews" HorizontalAlignment="Left" Margin="380,124,0,0" VerticalAlignment="Top" Width="162" Text="Select ..." SelectionChanged="cmbView">
<ComboBoxItem Content="Company" Foreground="#FFA2A2A2"/>
<ComboBoxItem Content="Employee" Foreground="#FFA2A2A2"/>
</ComboBox>
I suspect that you have basically designed your WPF application as if it were a WinForms application, setting exact Height and Width values on your UI elements. That is not how we layout UI elements in WPF. If you did do that, then you are correct that putting them in a DockPanel will not fix your problem.
In WPF, we generally use Grid elements to make full use of the available space provided to them. Setting a Grid.ColumnDefinition.Width to Auto and another to * will fill *all of the available width:
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" /> <!-- Just big enough for content -->
<ColumnDefinition Width="*" /> <!-- Fills all remaining space -->
</Grid.ColumnDefinitions>
...
<TextBlock Grid.Column="1" Text="I'm in the right cell" />
That's just one example of many... Please read through the Introduction to WPF Layout page from the WPF Tutorial.net website for more information.
The problem you describe is actually quite easy to solve, you simply NEVER use a fixed size for anything. All your panels have to be sized relative to something.
Changing the resolution of a screen is literally the same as changing the size of your window. If it works with a Window.Size of 1024x768 it will work at a 1024x768 resolution.
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="384" Width="525">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition />
</Grid.RowDefinitions>
<!-- Pretend I'm a logo -->
<Border Height="23" Width="75" HorizontalAlignment="Left" Background="Blue" CornerRadius="5" Padding="3">
<TextBlock Foreground="White">Logo</TextBlock>
</Border>
<WrapPanel Grid.Row="0" Grid.Column="1" HorizontalAlignment="Right" Orientation="Horizontal">
<TextBlock Text="About" Margin="6"/>
<TextBlock Text="Home" Margin="6"/>
<TextBlock Text="Help" Margin="6"/>
<TextBlock Text="Settings" Margin="6"/>
</WrapPanel>
<ListBox Grid.Row="1" Grid.Column="0"
BorderThickness="0">
<TextBlock Text="Example" Margin="6"/>
<TextBlock Text="Example" Margin="6"/>
<TextBlock Text="Example" Margin="6"/>
<TextBlock Text="Example" Margin="6"/>
<TextBlock Text="Example" Margin="6"/>
<TextBlock Text="Example" Margin="6"/>
<TextBlock Text="Example" Margin="6"/>
<TextBlock Text="Example" Margin="6"/>
<TextBlock Text="Example" Margin="6"/>
<TextBlock Text="Example" Margin="6"/>
</ListBox>
<Grid Grid.Row="1" Grid.Column="1">
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Border >
<Border.Background>
<LinearGradientBrush StartPoint="0,0" EndPoint="1,1">
<GradientStop Color="Red" />
<GradientStop Color="White" Offset="1"/>
</LinearGradientBrush>
</Border.Background>
<TextBlock>I'm a Data Grid</TextBlock>
</Border>
<GridSplitter Grid.Row="1" VerticalAlignment="Top" Height="3"/>
<Border Grid.Row="1" Margin="0,3,0,0">
<Border.Background>
<LinearGradientBrush StartPoint="0,0" EndPoint="1,1">
<GradientStop Color="Blue" />
<GradientStop Color="White" Offset="1"/>
</LinearGradientBrush>
</Border.Background>
<TextBlock>I'm a Data Grid</TextBlock>
</Border>
</Grid>
</Grid>
</Window>
The gradients are there so you can see its working when you resize.
If you've already designed to a fixed resolution then an easy hack is to wrap everything in a ViewBox and give the encapsulating child the same dimensions as the resolution you designed for. So if you designed for 1600 x 900 and your main window contained this:
<Grid>
<TextBlock Text="Big Text" FontSize="100" />
</Grid>
...then replace it with this:
<Viewbox Stretch="Uniform">
<Grid Width="1600" Height="900">
<TextBlock Text="Big Text" FontSize="100" />
</Grid>
</Viewbox>
Then make a mental note to do your UI design properly from day 1 next time.
Related
I have a Grid in another Grid and add the second Grid into ScrollViewer but don't see scrollbar for it. The grid i add ScrollViewer has the name InfoGrid. I dont understand why ScrollViewer is not working. Is there any alternative way you can suggest me ? My xaml code for the all window :
<Window x:Class="ModelView.KillCardCheck"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="Auto" Height="Auto" SizeToContent="WidthAndHeight"
ResizeMode="NoResize" Icon="pack://application:,,,/Resources/image/ffdc_gui.png"
xmlns:lex="http://schemas.root-project.org/xaml/presentation" Closing="WindowClosing">
<Grid Style="{DynamicResource GridStyle}" HorizontalAlignment="Stretch"
VerticalAlignment="Stretch">
<Grid.RowDefinitions>
<RowDefinition Height="12"/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition Height="40"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="11"/>
<ColumnDefinition Width="109"/>
<ColumnDefinition Width="250"/>
<ColumnDefinition Width="100"/>
</Grid.ColumnDefinitions>
<DataGrid Grid.Column="1" Grid.ColumnSpan="3" Grid.Row="2" Style="{DynamicResource {x:Type DataGrid}}"
AutoGenerateColumns="False" CanUserSortColumns="False" CanUserAddRows="False"
Margin="4,4,4,4" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" RowHeight="25" Name="dgKillCardChecks"
SelectionMode="Single" BorderThickness="1,1,1,0">
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding Number}"
Width="30" IsReadOnly="True">
</DataGridTextColumn>
<DataGridTemplateColumn Header="{lex:LocText Key=check_list, Dict=language, Assembly=FfdcLocalization}" Width="*" >
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<CheckBox Name="chkCheckList" Content="{Binding CheckItem}"
Click="CheckListCheckBoxOnClick"
Tag="{Binding Index}"
IsChecked="{Binding Path=CheckStatus, UpdateSourceTrigger=PropertyChanged}"
IsHitTestVisible="{Binding Enabled}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
<ScrollViewer VerticalScrollBarVisibility="Visible">
<Grid Style="{DynamicResource GridStyle}" Grid.Row="3" Grid.Column="1" Grid.ColumnSpan="3" Margin="4,4,4,4" Name="InfoGrid" >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
</Grid>
</ScrollViewer>
<TextBlock Name="descriptionBlock" TextWrapping="Wrap" Grid.Row="1" Grid.Column="1" Grid.ColumnSpan="3" Margin="4,4,4,4"></TextBlock>
<Button Style="{DynamicResource {x:Type Button}}" Grid.Row="4" Grid.Column="3" Grid.ColumnSpan="1"
x:Name="btnQuit" MaxHeight="30" Margin="2,4,0,6" MaxWidth="120" MinWidth="80"
Content="{lex:LocText Key=close, Dict=language, Assembly=FfdcLocalization}"
VerticalContentAlignment="Center" MinHeight="30" VerticalAlignment="Center" HorizontalAlignment="Left" Click="CloseClick"/>
<Button Style="{DynamicResource {x:Type Button}}" Grid.Row="4" Grid.Column="1" Grid.ColumnSpan="2"
x:Name="btnClear" MaxHeight="30" Margin="2,4,0,6" MaxWidth="200" MinWidth="80"
Content="{lex:LocText Key=clear_killcard, Dict=language, Assembly=FfdcLocalization}"
VerticalContentAlignment="Center" MinHeight="30" VerticalAlignment="Center" HorizontalAlignment="Right" Click="ClearKillCardClick"/>
</Grid>
</Window>
The ScrollViewer that you made has no grid.Row set, instead you put it on the grid inside it. That does not make much sense since the grid ("Info Grid") is inside the ScrollViewer so it's parent is the ScrollViewer. You might want to try setting the ScrollViewer row and column.
I need to glue content to window sides, would also like to add a gridsplitter to resize internal control separation, and the status bar creates whitespace.
The Grid won't resize vertically with the bottom of the window for instance.
Currently, I am yet unaware of the cause or resolution, starting to go blind on the code. I could use a second pair of eyes.
Change Heights into MinHeights, use Grid containers, etc.
Pretty much anything I could find and think of, including staring down the code...
<Window x:Class="Teachers_Lounge.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
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"
xmlns:local="clr-namespace:Teachers_Lounge"
mc:Ignorable="d"
Title="Teachers Lounge"
Height="625"
Width="1525"
MinHeight="625"
MinWidth="1525"
KeyDown="Window_KeyDown"
Closing="Window_Closing" Loaded="Window_Loaded">
<Window.Resources>
<DataTemplate x:Key="CalendarTemplate">
<Grid Margin="1">
<Grid.RowDefinitions>
<RowDefinition Height="20" />
<RowDefinition Height="20" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="265" />
<ColumnDefinition Width="50" />
</Grid.ColumnDefinitions>
<DockPanel Grid.Row="0" Grid.Column="0">
<TextBlock FontWeight="Bold" Text="Name:" DockPanel.Dock="Left" Margin="5,0,10,0" />
<TextBlock Text="" />
<TextBlock Text="{Binding EventName}" Foreground="Green" FontWeight="Bold" />
</DockPanel>
<DockPanel Grid.Row="1" Grid.Column="0">
<TextBlock FontWeight="Bold" Text="Date:" Foreground="DarkGray" DockPanel.Dock="Left" Margin="5,0,5,0" />
<TextBlock Text="{Binding EventDateTime}" />
</DockPanel>
<Grid Grid.Column="1" Grid.RowSpan="2" VerticalAlignment="Top" HorizontalAlignment="Right" Margin="-5,0,5,0">
<Button x:Name="EditEvent_Button" Width="40" Height="15" Margin="0,5,0,0" VerticalAlignment="Top" BorderThickness="0" Background="LightGray" CommandParameter="{Binding}" Command="{Binding ElementName=Window, Path=OnClickEditEvent}" Click="EditEvent_Button_Click">
<TextBlock Margin="0, -2">Edit</TextBlock>
</Button>
<Button x:Name="DeleteEvent_Button" Width="40" Height="15" Margin="0,20,0,5" VerticalAlignment="Bottom" BorderThickness="0" Background="LightGray" CommandParameter="{Binding}" Command="{Binding ElementName=Window, Path=OnClickDeleteEvent}" Click="DeleteEvent_Button_Click">
<TextBlock Margin="0, -2">Delete</TextBlock>
</Button>
</Grid>
</Grid>
</DataTemplate>
</Window.Resources>
<Grid MinHeight="586" VerticalAlignment="Top">
<Grid.RowDefinitions>
<RowDefinition Height="50" />
<RowDefinition Height="*" />
<RowDefinition Height="20" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="360" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBox x:Name="DateAndTime" Grid.Row="0" Grid.Column="0" HorizontalAlignment="Left" Height="30" Margin="10,10,0,0" TextWrapping="Wrap" Text="dddd dd mmmm HHh" VerticalAlignment="Top" Width="350" FontSize="20" IsEnabled="False"/>
<TextBox x:Name="Topic" Grid.Row="0" Grid.Column="1" Margin="10,10,77,10" TextWrapping="Wrap" Text="Topic" FontSize="20" FontWeight="Bold" KeyDown="Topic_KeyDown" LostFocus="Topic_LostFocus" />
<Button x:Name="Settings_Button" Grid.Column="1" Margin="0,10,10,10" FontWeight="Bold" Click="Settings_Button_Click" HorizontalAlignment="Right" Width="62">Settings</Button>
<Grid Grid.Row="1" Grid.Column="0"
Margin="10,0,0,0">
<Grid.RowDefinitions>
<RowDefinition Height="20" />
<RowDefinition Height="489*" />
<RowDefinition Height="7*"/>
</Grid.RowDefinitions>
<Menu BorderThickness="1 1 1 0" BorderBrush="Black">
<Menu.ItemsPanel>
<ItemsPanelTemplate>
<DockPanel HorizontalAlignment="Stretch"/>
</ItemsPanelTemplate>
</Menu.ItemsPanel>
<MenuItem Header="New Event" Click="NewReplacement_Click" />
</Menu>
<ListBox x:Name="CalendarList" Grid.Row="1"
BorderThickness="1 0 1 1" BorderBrush="Black"
HorizontalAlignment="Left" MinWidth="350" MinHeight="485" VerticalAlignment="Top"
ItemsSource="{Binding Tables[0]}" ItemTemplate="{StaticResource CalendarTemplate}" KeyDown="CalendarList_KeyDown"/>
</Grid>
<Grid Grid.Row="1" Grid.Column="1"
HorizontalAlignment="Left" MinHeight="485" MinWidth="1072" VerticalAlignment="Top" Margin="10,0,10,0">
<Grid.RowDefinitions>
<RowDefinition Height="20" />
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Menu BorderThickness="1 1 1 0" BorderBrush="Black">
<Menu.ItemsPanel>
<ItemsPanelTemplate>
<DockPanel HorizontalAlignment="Stretch"/>
</ItemsPanelTemplate>
</Menu.ItemsPanel>
<MenuItem Header="🠜" Click="ExcelPreviousDate_Click" />
<MenuItem Header="🡄" Click="ExcelPreviousWeek_Click" />
<MenuItem x:Name="ExcelActiveTimewindow" Header="Week XX, Date dd-MM-yy" IsEnabled="False" />
<MenuItem Header="🡆" Click="ExcelNextWeek_Click" />
<MenuItem Header="🠞" Click="ExcelNextDate_Click" />
<Separator />
<MenuItem Header="New Replacement" Click="NewReplacement_Click" />
<MenuItem Header="Delete Replacements" HorizontalAlignment="Right" Click="DeleteReplacements_Click" />
</Menu>
<DataGrid Name="ExcelDataView" Grid.Row="1"
BorderThickness="1 0 1 1" BorderBrush="Black"
AutoGenerateColumns="False"
ColumnWidth="*"
RowBackground="WhiteSmoke"
Background="LightBlue"
CanUserAddRows="False"
BeginningEdit="ExcelDataView_BeginningEdit"
CellEditEnding="ExcelDataView_CellEditEnding"
RowEditEnding="ExcelDataView_RowEditEnding"
SelectionChanged="ExcelDataView_SelectionChanged"
MinWidth="1077" MinHeight="485" HorizontalAlignment="Left" VerticalAlignment="Top">
<DataGrid.ColumnHeaderStyle>
<Style TargetType="DataGridColumnHeader">
<EventSetter Event="Click" Handler="OnExcelHeaderClicked" />
</Style>
</DataGrid.ColumnHeaderStyle>
<DataGrid.Columns>
<DataGridTextColumn Header="Time" Binding="{Binding TimeText, Mode=TwoWay}" Width="70" CanUserSort="False" />
<DataGridTextColumn Header="Replaced User" Binding="{Binding ReplacedUser, Mode=TwoWay}" Width="140" CanUserSort="False" />
<DataGridTextColumn Header="Replacement User" Binding="{Binding ReplacementUser, Mode=TwoWay}" Width="140" CanUserSort="False" />
<DataGridTextColumn Header="Class" Binding="{Binding Class, Mode=TwoWay}" Width="170" CanUserSort="False" />
<DataGridTextColumn Header="Location" Binding="{Binding Location, Mode=TwoWay}" Width="170" CanUserSort="False" />
<DataGridTextColumn Header="Info" Binding="{Binding AdditionalInfo, Mode=TwoWay}" CanUserSort="False" />
<DataGridCheckBoxColumn Header="Mark" Binding="{Binding Marked, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" CanUserSort="False" Width="50">
<DataGridCheckBoxColumn.CellStyle>
<Style>
<EventSetter Event="CheckBox.Checked" Handler="OnExcelDeleteColumnChecked"/>
<EventSetter Event="CheckBox.Unchecked" Handler="OnExcelDeleteColumnUnchecked"/>
</Style>
</DataGridCheckBoxColumn.CellStyle>
</DataGridCheckBoxColumn>
</DataGrid.Columns>
</DataGrid>
</Grid>
<Menu Grid.Row="3" Grid.ColumnSpan="2"
BorderThickness="0 1 0 0" BorderBrush="Black" IsEnabled="False"
VerticalAlignment="Bottom" Height="20">
<Menu.ItemsPanel>
<ItemsPanelTemplate>
<DockPanel HorizontalAlignment="Stretch"/>
</ItemsPanelTemplate>
</Menu.ItemsPanel>
<MenuItem MinWidth="1111" BorderThickness="0">
<MenuItem.Header>
<TextBlock x:Name="StatusbarMessage"
HorizontalAlignment="Left" VerticalAlignment="Center"
TextAlignment="Left" />
</MenuItem.Header>
</MenuItem>
<MenuItem BorderThickness="0"
HorizontalAlignment="Right" HorizontalContentAlignment="Right" Width="350" >
<MenuItem.Header>
<TextBlock x:Name="StatusbarInfo"
VerticalAlignment="Center" Width="335"
TextAlignment="Right" />
</MenuItem.Header>
</MenuItem>
</Menu>
</Grid>
</Window>
A proper layout that resizes as it should is what I'd expect.
Some weird behavior and glue-ing are what is happening though.
I have a datagrid where if a row is clicked upon the row details is shown. In the row details is another datagrid called dgRights.
So dgRights is bound to SelectItem.Funds where funds is a custom list. dgRights show 4 columns, 3 of which are bound fine however the fourth isn't (in my code below its called "Rights Sedol").
I want the column Rights Sedol to be bound to a property of the selectedItem not selectedItem.Funds, is this possible?
I've tried the lines of code below without luck,
<DataGridTextColumn Header="Rights Sedol" Binding="{Binding SelectedItem.NewSecurity.Sedol, RelativeSource={RelativeSource AncestorType=Window}}/>
2nd
<DataGridTextColumn Header="Rights Sedol" Binding="{Binding SelectedItem.NewSecurity.Sedol, RelativeSource={RelativeSource AncestorType=DataGrid}}/>
I also tried changing the ItemSource of the datagrid from SelectedItem.Funds to just SelectItem & changed the other 3 working columns to Funds.Code etc but this didn't display any data in the datagrid at all. So not sure what to do?
App.xaml - my row details data template
<DataTemplate x:Key="DG_RowDetailRGHTSHist">
<Grid x:Name="RowDetailGrid"
Margin="5"
HorizontalAlignment="Left">
<Border HorizontalAlignment="Left"
VerticalAlignment="Top"
Height="250"
CornerRadius="5">
<Border.Background>
<LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
<GradientStop Offset="0" Color="Transparent"/>
<GradientStop Offset="1" Color="Transparent"/>
</LinearGradientBrush>
</Border.Background>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="4*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="400"/>
<ColumnDefinition Width="200"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Row="0"
Grid.Column="0"
Margin="5,5,5,5"
HorizontalAlignment="Left"
FontSize="12"
FontWeight="Bold"
Foreground="Black"
Text="Fund Summary">
</TextBlock>
<DataGrid Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2"
ItemsSource="{Binding SelectedItem.Funds, RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}"
RowStyle="{StaticResource DG_Row}"
ColumnHeaderStyle="{StaticResource DG_ColumnHeader}"
RowHeaderStyle="{StaticResource DG_RowHeaderNested}"
CellStyle="{StaticResource DG_Cell}"
Background="Silver"
HorizontalGridLinesBrush="LightGray"
VerticalGridLinesBrush="LightGray"
CanUserAddRows="False"
CanUserDeleteRows="False"
Margin="50,5,5,20"
AutoGenerateColumns="False">
<DataGrid.Columns>
<DataGridTextColumn Header="Fund Code" Binding="{Binding Code}" IsReadOnly="True" MinWidth="75"/>
<DataGridTextColumn Header="Fund Code SS" Binding="{Binding CodeSS}" IsReadOnly="True" MinWidth="75"/>
<DataGridTextColumn Header="Rights Sedol" Binding="{Binding SelectedItem.NewSecurity.Sedol, RelativeSource={RelativeSource AncestorType=Window}}" IsReadOnly="True" MinWidth="75"/>
<DataGridTextColumn Header="Number of Rights" Binding="{Binding CurrentNominal, Mode=TwoWay, StringFormat={}{0:N0}}" IsReadOnly="True"/>
</DataGrid.Columns>
</DataGrid>
</Grid>
</Border>
</Grid>
</DataTemplate>
You want to access the 2nd datagrid up so you need to specify AncestorLevel=2.
{RelativeSource AncestorType=DataGrid, AncestorLevel=2}}
I am working on a wpf bingo app for learning.
When the app is in full screen it looks how i want it:
However, when the window is minimized the elements move out of the positions I want them:
what can I do to stop this and keep the elements in one place no matter what window size.
Below is my complete XAML code:
<Window x:Class="Bingo_Game.MainGame"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:Bingo_Game"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
Title="MainGame" WindowStartupLocation="CenterScreen" WindowState="Maximized" Height="704.2">
<Window.Background>
<ImageBrush ImageSource="Images/background.jpg"/>
</Window.Background>
<Grid>
<DataGrid Name="grid" ItemsSource="{Binding}" Height="300"
AutoGenerateColumns="False" HeadersVisibility="None" Background="Transparent" BorderThickness="0" CanUserAddRows="false"
VerticalScrollBarVisibility="Disabled" HorizontalAlignment="Center" VerticalAlignment="Top" RowHeight="40" Margin="10,0" HorizontalContentAlignment="Center">
<DataGrid.Resources>
<local:ItemExistInRangeConverter x:Key="ItemExistInRangeConverter"/>
<Style x:Key="BackgroundColourStyle" TargetType="{x:Type TextBlock}">
<Style.Triggers>
<DataTrigger Value="True">
<DataTrigger.Binding>
<MultiBinding Converter="{StaticResource ItemExistInRangeConverter}">
<Binding Path="Text" RelativeSource="{RelativeSource Self}"/>
<Binding Path="DataContext.RangeNumbers"
RelativeSource="{RelativeSource FindAncestor,
AncestorType=DataGrid}"/>
</MultiBinding>
</DataTrigger.Binding>
<Setter Property="Background" Value="LightGreen" />
</DataTrigger>
</Style.Triggers>
</Style>
</DataGrid.Resources>
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding Path=Number}"
ElementStyle="{StaticResource BackgroundColourStyle}" MinWidth="65">
</DataGridTextColumn>
</DataGrid.Columns>
<DataGrid.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Orientation="Vertical" />
</ItemsPanelTemplate>
</DataGrid.ItemsPanel>
</DataGrid>
<Button Content="Roll Number" Margin="333,139,323,484" Width="104" Click="newNumber" Height="50" RenderTransformOrigin="-1.01,-1.46" HorizontalAlignment="Center" VerticalAlignment="Center" >
<Button.Effect>
<DropShadowEffect/>
</Button.Effect>
</Button>
<TextBlock HorizontalAlignment="Center" Margin="240,187,217,340" TextWrapping="Wrap" Name="number" VerticalAlignment="Center" Height="146" Width="303" FontSize="120" FontWeight="Bold" TextAlignment="Center" Foreground="Black" Grid.IsSharedSizeScope="True"/>
<DataGrid HorizontalAlignment="Left" Margin="0,544,0,0" VerticalAlignment="Top" RenderTransformOrigin="-2.917,-2.923" Height="119" Width="330" Name="calledGrid" ItemsSource="{Binding}" />
<TextBlock HorizontalAlignment="Center" Height="33" Margin="240,333,226,307" TextWrapping="Wrap" VerticalAlignment="Center" Width="294" Name="noneLeft" FontSize="16" FontWeight="Bold" TextAlignment="Center" />
<TextBlock HorizontalAlignment="Center" Height="33" Margin="240,300,226,340" TextWrapping="Wrap" VerticalAlignment="Center" Width="294" Name="callTB" TextAlignment="Center" FontSize="20" />
</Grid>
</Window>
In addition to the MSDN link DROP table users listed, have a read of this overview of the WPF Panel elements to get a feel for how to approach UI layout in WPF. ALhtough you can drag and drop (and resize) your controls within Visual Studio, it often leads to layouts that don't scale well, and introduces additional compilacations (the extra Margin properties on many of your controls).
If you aren't going to stop your users from resizing your control, it's worth thinking about how you'd like the elements behave when the window is manipulated, should elements scale, move around, stay fixed to a particular window edge, etc.
There are many different ways to layout your UI with the various panels, but your desired behaviour dictates which is the easiest/most appropriate.
Here's a small (but not very neat) mock up using a Grid, to roughly approximate your first case (some of your elements replaced by a few simple labels).
<Grid Background="Transparent">
<Grid.RowDefinitions>
<RowDefinition Height="2*" />
<RowDefinition Height="*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Label Content="Your DataGrid" Grid.Column="1" Grid.Row="0" Background="Red" Grid.ColumnSpan="3"/>
<Label Content="Your Other DataGrid" Grid.Column="0" Grid.Row="1" Background="Green" Grid.ColumnSpan="2"/>
<Label Content="Your Button" Grid.Column="2" Grid.Row="2" Background="Gray" Height="40" Width="100"/>
<Label Content="41" Grid.Column="2" Grid.Row="1" Background="White" HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="30"/>
</Grid>
It will produce something that looks like this:
Play around resizing it, some elements will stretch, some (with fixed height/width), will remain the same size, and move around relative to the window size.
If you wish to dock elements to the side of your window, have a look at the DockPanel, if you need to collect a few controls together, check out the StackPanel.
Check this out. It points out that to prevent this you can set up a grid and put the elements in defined size columns and rows to keep them from re-sizing with the window.
Also, a good article that you may look at here about Windows Presentation Foundation (WPF) layout system.
I have a WPF user control inside windows form project and I have a problem. Every second time my app crashes as element host can't load data in user control.
Same thing happens when I put this in WPF project. Every second time my app starts normally.
Any idea what could be the problem? This is my user control code:
<UserControl x:Class="Fleet_management.Info"
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"
mc:Ignorable="d" Height="492" Width="578">
<UserControl.Background>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#FFE2E2E2" Offset="0" />
<GradientStop Color="White" Offset="1" />
</LinearGradientBrush>
</UserControl.Background>
<UserControl.Resources>
<XmlDataProvider x:Key="rssData" XPath="//item" Source="******" />
</UserControl.Resources>
<Grid Margin="3" Height="598" Width="565">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="252*" />
<ColumnDefinition Width="90*" />
<ColumnDefinition Width="223*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="177*" />
<RowDefinition Height="55*" />
<RowDefinition Height="122*" />
<RowDefinition Height="177*" />
</Grid.RowDefinitions>
<ListBox x:Name="lstItems" Margin="3,0" ItemsSource="{Binding Source={StaticResource rssData}}"
SelectedIndex="0" VerticalAlignment="Stretch" FontStretch="Normal" FontSize="14" FontFamily="Lucida Sans Unicode" Grid.ColumnSpan="3">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Image Width="20" Margin="3" Source="{Binding XPath=enclosure/#url}" />
<TextBlock Margin="3" VerticalAlignment="Center" Text="{Binding XPath=title}" FontWeight="Bold" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<StackPanel Grid.Row="1" Orientation="Vertical" DataContext="{Binding ElementName=lstItems, Path=SelectedItem}" Margin="0,0,0,5" Grid.ColumnSpan="3">
<TextBlock Margin="3" FontSize="13" FontWeight="Bold" Text="{Binding XPath=title, Path=InnerText}" />
<TextBlock Margin="3" Opacity="0.72" Text="{Binding XPath=pubDate}" />
</StackPanel>
<ScrollViewer CanContentScroll="True" Grid.Row="2" HorizontalScrollBarVisibility="Disabled" VerticalScrollBarVisibility="Auto" DataContext="{Binding ElementName=lstItems, Path=SelectedItem}" Margin="0,0,3,115" Grid.RowSpan="2" Grid.ColumnSpan="3">
<TextBlock Margin="3"
FontStyle="Italic" Text="{Binding XPath=description, Path=InnerText}" TextWrapping="Wrap" TextAlignment="Justify" AllowDrop="False"
Foreground="#FF0000E7" FontFamily="Lucida Sans Unicode" FontSize="14" Padding="0,0,5,0" VerticalAlignment="Center" />
</ScrollViewer>
</Grid>
</UserControl>
You might want to check if the xml document that contains the data is still locked by the previous app.
So, start up the app. Close it. Check to see if the xml file is still in use.
Also,: add exception handling so you know what exception is being thrown. Use at least Application.DispatherUnhandledException