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. :)
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
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.
I've searched loads for an answer to my problem.
Basically on my WP8 app, I have an "add record" page and a list of text boxes. I can scroll up and down the full length of the page fine, but when I tap one of the text boxes and the keyboard appears, I can no longer scroll to the very bottom and therefore can't complete the last couple text boxes.
Now, if you have a look at the MS calendar app on WP8, the "new appointment" page has a similar thing - when you tap one of the text boxes you can still scroll the whole way up and down.
I was wondering, is there anywhere I can see the XAML that MS have used? Then I can learn from that. I'm sure it's as simple as setting a height property or something but I've been stumped on this for a while now.
Rather than posting my XAML etc, does anyone know where I can get a look at the XAML for the MS stock apps? If this is even possible...
Thanks
I had the same issue. but at last i solved it, i just used the Height property to do this. i already answered for the same type of problem posted by someone.Please do the following steps
First create a ScrollViewer
Indide the ScrollViewer create a container(eg: Grid/StackPanel/Border etc...) and put every controlls inside it.
Set fixed Height for ScrollViewer and the Container (Note: Height of container should be greater than ScrollViewer's Height)
See the below Code
<ScrollViewer Height="500">
<Grid Name="Container" Height="700">
<TextBox/>
<TextBox/>
<TextBox/>
</Grid>
</ScrollViewer>
Now you can scroll the container Grid Even the KeyBoard shown or even focus on a TextBox.
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
I have a path defined as such:
<Viewbox Visibility="Collapsed" x:Name="Tick" Grid.Column="1" Grid.Row="1">
<Canvas MaxWidth="100" MaxHeight="100" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="100" Height="100" Canvas.Left="0" Canvas.Top="0">
<Path ...Fill="#FF00B800" x:Name="MyPath" (path dimensions, lines, etc) .../>
</Canvas>
</Viewbox>
Now what I'd like to do is manipulate fill such that it will cause the path to have a fade in/fade out effect. Basically make fills alpha component either move towards opaque or transparent based on whether or not the viewbox the path is inside is Visible. So when visible the path fades in, when collapsed the path fades out.
The effect you are trying achieve is a classy one but there is a serious problem with your current plan. When the Visibility of a higher-level element, Viewbox in this case, is set to Visibility.Collapsed, the element and all sub-elements are immediately no longer visisble. It is at this point that you want the fade-out of the Path to begin.
So the Path is already not visible and starting an animation to gradually reduce its opacity will no do any good because it is already gone. In other words, by the time the visibility is set to Visiblity.Collapsed, it is too late to do anything useful with things inside the element because the user won't see them. If you could, you would want to see into the future and know that you are going to change the visibility and start an animation so that it finishes before you "close the curtain" on the element.
The same problem doesn't apply to when we make the element visible because everything is perfect: we become visible and start the fade-in animation. But since half of the effect is not going to work, we still have a big problem.
The solution to this problem is move up a level and see what we're trying to do. In the XAML we only have passive elements, Viewbox, Canvas, and Path. But maybe these are acting more like controls or assisting controls, for example being the check for a CheckBox or a checkbox-like control.
A control can have states:
Normal, MouseOver
Pressed, Disabled
Unfocused, Focused
and those states can have transition effects, thanks to the VisualStateManager.
So if the fade-in and fade-out effects are part of control behavior, then we have a whole sophisticated powerful toolset available to solve our problem. I don't know if this is the case in your situation.
Even if it is not the case, a very workable approach to transition effects on Silverlight is to transform your elements into a lookless control, solely for the purpose of utilizing the VisualStateManager, because it makes things so easy. Perhaps this alternative can work in your situation.