I've created a datagrid and placed it in a spot in a WPF form.
Now what I'm trying to do is have the datagrid change its size keeping the same proportions as its original placement with the WPF window changing size (hopefully that makes sense).
I've tried setting autostretch to true but that hasn't helped.
Got my computer with Visual Studio in my office, so can't test it :) but shouldn't this work if you set the alignments to stretch?
datagridObj.HorizontalAlignment = System.Windows.HorizontalAlignment.Stretch;
datagridObj.VerticalAlignment = System.Windows.VerticalAlignment.Stretch;
Sure it makes sense, but it sounds like you don't really understand how the WPF layout system works, and unless you do it will be really painful going forward. The short story is, you need to have an appropriate container - I recommend Grid - and have your DataGrid placed in that container. Then you can set margins and so on for the DataGrid to place it however you like, and provided it has its Width and Height set to Auto, it will keep with its parent container.
Now if you have several other controls in the picture, of course it's a bit more involved, but I still recommend keeping with Grids and splitting them into however many rows and columns you require, then setting the appropriate values for their Height/Width respectively - you can make some columns fixed in width, or a multiple of other column, or leave them as Auto and they will take up the remainder of the space.
The topic is much more involved of course, but you can find a quick primer on MSDN: http://msdn.microsoft.com/en-us/library/ms745058.aspx
If you'll remember just one thing, it should be this: Grids represent fluid layouts in WPF, use them as much as possible as opposed to Canvases. Of course StackPanel and DockPanel etc. have their own specific uses.
P.S. The visual studio designer makes a bit of mess of things usually, by setting margins and so on to make the drag and drop more intuitive, you should pay close attention to the properties it modifies and see if you're not better off positioning things manually by modifying the XAML (you usually are) once you sketched the layout out.
just as example
<Window x:Class=""
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<DataGrid Margin="162,57,141,54"/>
</Grid>
</Window>
by default a DataGrid is
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
so you only need a Margin like Arno Saxena told you
Related
I understand that there are a variety of ways to size child elements according to parent elements. If you're using a grid for example, you can use row and column definitions and you get lots of freedom regarding automatic sizes or fixed sizes or "star" sizes. However, if the child elements themselves have a fixed width and height then it won't matter if the parent tells the child to fill all available space. The child element will remain the same size.
I have a window that was designed to always display its contents at the same pixel dimensions no matter what size the window is resized to. Rather than go and change every single child element in every XAML page so that it doesn't have a fixed size, I'd like to get the main Grid to just scale to fit the window. So far the only way to get elements with fixed dimensions to display at different sizes is to use Transform scaling, either with a RenderTransform or a LayoutTransform. But if I go that route, I'll have to code the scaling in C# to respond to resizing events rather than have it happen automatically. Is there some native builtin way to do this in XAML? This feels like the kind of thing I should be able to do with some special property, or perhaps a ContentControl or ContentPresenter.
I've seen Resize WPF Window and contents depening on screen resolution but it's asking about conventional resizing and not scaling fixed elements. I've also seen How to make all controls resize accordingly proportionally when window is maximized? and that has the same problem though the second answer at least talks about handling resizing events.
Here's a simplified example of a fixed-dimension child element not resizing as desired:
<Window x:Class="WpfTest.Window1"
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"
mc:Ignorable="d"
Title="Window1" Height="200" Width="300" Background="LightBlue">
<Grid>
<Frame Background="Blue" Width="200" Height="100">
</Frame>
</Grid>
</Window>
Actual results:
Desired results:
As you can see, what I'm looking for is a sort of letterboxing effect, meaning I want the aspect ratio to be maintained. However, I haven't found a way to get automatic scaling even without worrying about the aspect ratio, so I thought I'd consider the letterboxing as a sort of second phase that I'd worry about later.
The control you are looking for is a Viewbox. It grows to fill its container (you can set the stretch style for the letterboxing) and scales all its contents accordingly. Just make it the root element of your application (or whatever you want stretched):
<Viewbox>
<Grid> //Or whatever
<OtherStuff>
</Grid>
</Viewbox>
Note that because the viewbox is scaling its contents traditional Grid behavior and similar will stop working since the size of the content never actually changes.
Another option is to use a MultiValueConverter to set the height and width.
You could give the Converter the ActualWidth and ActualHeight of the root container als parameters and let it calculate the needed aspect ratio.
A tutorial which describes the MultiValueConverter:
http://www.wpftricks.com/2017/05/wpf-multivalueconverter.html
When a ScrollViewer has scrollbars showing, and the cursor is not moved for around 3 seconds, the scrollbars auto hide.
Is there a way to set that time to more or less than the default time?
EDIT
Reproduce so:
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<ScrollViewer Height="500" Width="500">
<Grid Background="Blue" Height="1000" Width="1000">
</Grid>
</ScrollViewer>
</Grid>
Move the cursor over the ScrollViewer to show the scrollbar. Leave the cursor motionless for 3 seconds to see the scrollbar disappear. I want to change those 3 seconds to 1.
EDIT 2
Follow-up question - Why does this ScrollViewer's ScrollBars appear twice? .
I suppose I need to start breaking the habit of doing quickie answers in comments anyway so;
Carrying from the original comments above. The control style templates for Scrollbar have embedded ThemeAnimation's for FadeIn/FadeOut nested in various states in the VisualStateManager portion.
Being that they're animations inheriting in order of;
Object -> DependencyObject -> Timeline
...they do support Dependency Properties such as BeginTime and Duration that allows us to alter the default behavior of their action. So to remedy your scenario you have the options of either removing them entirely from their respective states within the VisualStateManager or you can alter the properties to better suit your needs of your own timeline requirements.
Doing this is just a matter of extracting the control template using either VS or Blend and either applying changes explicitly to a copy of the template or overriding the default globally.
Glad you found your remedy. :)
I'm new in WPF so this is a very dummy question.
In Visual Studio -> Properties when I select a StackPanel (for example), I have the property Width. In this property I can click in the little square on the right and a menu is open. One of the option in the menu is "Custom Expression"
So here is my question:
Is possible to define Width and Height base in a Mathmatic expression?
<StackPanel Width="{Parent.Width - 100}">
</StackPanel>
Or something like that?
EDIT
I'm asking this because i'm intend to create a StackPanel that need to have a width 100 pixels lower than the Window. When window size was changed the StackPanel need to change to corresponding to this rule.
By default you cannot, and you have to use converters. Of course, especially since you are new in WPF, writing converters over and over for every simple operation like that might feel painful to you. So there are some custom markup extensions to reduce that pain. For example: https://quickconverter.codeplex.com/ (but there are others). With them it looks like that:
<Window x:Class="WpfApplication2.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:qc="http://QuickConverter.CodePlex.com/"
mc:Ignorable="d"
Title="MainWindow" Height="500" Width="500" x:Name="self">
<Grid x:Name="LayoutRoot">
<Rectangle Fill="Red"
Width="{qc:Binding '$P-100', P={Binding ElementName=self, Path=ActualWidth}}"
Height="{qc:Binding '$P-100', P={Binding ElementName=self, Path=ActualHeight}}" />
</Grid>
</Window>
Here we bound width and height of a rectangle to parent "self" element dimensions minus 100, without use of explicit converters.
You can do this with a binding to the parent element's width/height. However, instead of doing that, why not use the dynamic layout and just define your child container with a margin - in your example 50px - so that its width would be 100px less than the parent container.
So the answer to the theoretical question of "Can I set a calculated value of a property based on another element?" is yes, use a binding with a converter that performs the necessary calculation.
To the more important question of "Is there a simpler way to do create a responsive layout that takes the parent container into account?" the answer is also yes, use container composition with margins, padding and alignment to get the desired effect.
Basically, I have a lot of xaml code that uses margins, and is base on the 1366x768 screen size. Unfortunately, my monitor is 1920x1080, so when it launches, my UI seems a little bit squished and the data is pushed to the wrong place. Is there a way to make my program launch in 1366x768 and not be allowed to change screen size?
Also maybe, if I do go 1080p, it still looks good - like, some of my ui elements just move across the page, and all my combo boxes just get huge
Does this all make sense? If not, just say :)
To answer your first question, all you need to do is set the "ResizeMode" property of the Window:
<Window x:Class="TestWPF.MainWindow"
....
Title="MainWindow"
ResizeMode="NoResize"
Height="1366" Width="768">
Regarding the second part of your question. I have a feeling that perhaps you're not quite using the available ways to lay out controls in WPF properly. UI Elements shouldn't move across the screen if you use Grids, DockPanels, and StackPanels to lay out your controls. I'd recommend you look at some examples. Post your XAML if you want a more specific suggestion regarding this :).
This is something that would be very useful during development. For example, my android phone allows "Show Layout Boundaries" as a Developer Option, e.g.
With this, I can see outlines of all layouts, including the padding and margins. Is there something like this in WPF that I could use to see how each element on the screen relates to the other elements?
In WPF the only thing that seems to be close it is ShowGridLines property in Grid:
Enabling Grid lines creates dotted lines around all the elements within a Grid. Only dotted lines are available because this property is intended as a design tool to debug layout problems and is not intended for use in production quality code. If you want lines inside a Grid, style the elements within the Grid to have borders.
Example:
<Grid ShowGridLines="True" ... />
For more information, see this link:
ShowGridLines Property Allows You to See Individual Cells in Grid
While the program is running, you might be interested in Snoop, which lets you inspect and highlight arbitrary elements of the interface and explode the window into a 3D view. It's not the same visual as you're looking for, but similarly useful.