Prevent manual scrolling of a ScrollViewer - silverlight

I have a ScrollViewer which wraps a bunch of dynamically created TextBox controls. The HorizontalScrollBarVisibility and VerticalScrollBarVisibility are both set to Hidden. I am programmatically scrolling the ScrollViewer in response to the user scrolling a gridview.
The problem i am having is that when the user places the focus on one of those TextBox elements and then presses the left/right arrow keys, the ScrollViewer is scrolling. I want to prevent this manual scrolling and only allow programmatic scrolling. Obviously disabling the ScrollViewer is not an option as the user needs to be able to add text to the TextBoxes inside it. Similarly, setting the HorizontalScrollBarVisibility property to Disabled doesn't work, as that resets the scroll offset back to zero.
How can i lock scrolling, or prevent manual scrolling?

By removing manual operation of the scroll bars, and hiding them, you are basically saying you want something that has a list of items, that can be scrolled from code, but is not a ListBox...
Conclusion: Don't use a ListBox :)
As you are managing the scrolling yourself, why not parent the TextBoxes under a StackPanel within a canvas (with a clipping rectangle of course). Then use the Canvas.Top/Left properties on the StackPanel to scroll it.
The example below does that. I added a slider bound to the Canvas.Top property so you can test it.
Xaml Example:
<UserControl x:Class="SilverlightApplication1.NotAListbox"
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"
d:DesignHeight="300" d:DesignWidth="400">
<Grid x:Name="LayoutRoot" Background="White">
<Canvas Background="Aquamarine" HorizontalAlignment="Center" Name="canvas1" VerticalAlignment="Center" Width="200" Height="200">
<Canvas.Clip>
<RectangleGeometry Rect="0,0,200,200"></RectangleGeometry>
</Canvas.Clip>
<StackPanel Canvas.Top="{Binding ElementName=slider1, Path=Value}" Name="stackPanel1">
<TextBox Height="23" Text="textBox 1" Width="120" />
<TextBox Height="23" Text="textBox 2" Width="120" />
<TextBox Height="23" Text="textBox 3" Width="120" />
<TextBox Height="23" Text="textBox 4" Width="120" />
<TextBox Height="23" Text="textBox 5" Width="120" />
<TextBox Height="23" Text="textBox 6" Width="120" />
<TextBox Height="23" Text="textBox 7" Width="120" />
<TextBox Height="23" Text="textBox 8" Width="120" />
<TextBox Height="23" Text="textBox 9" Width="120" />
</StackPanel>
</Canvas>
<Slider Height="171" HorizontalAlignment="Center" Margin="316,62,57,66" Name="slider1" VerticalAlignment="Center" Width="27" Orientation="Vertical" Minimum="-223" Maximum="200" />
</Grid>
</UserControl>

Related

Collapsed Tab Item Prevents Control Select in WPF Designer

I'm using Visual Studio Pro 2019, and I came across an issue when using the tab control. I created a test project to test switching between collapsed tabs programmatically, but found that, when in the designer, I'm unable to select the control within the tab when the tabs are collapsed. I found this answer confirming that the tab being collapsed is the issue.
My question is whether there is a fix for this that isn't just turning the tabs to visible, as it shifts the item's grid location.
The alternate solution could be to manually alternate the visibility of overlapping grids, but tabs seem to be the more appropriate solution.
xaml:
<Window x:Class="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:delete3"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800" Background="#FF424242">
<Grid>
<TabControl Name="Tabs" HorizontalAlignment="Left" Height="255" Margin="122,51,0,0" VerticalAlignment="Top" Width="437">
<TabItem Name="First" Header="TabItem" Visibility="Collapsed">
<Grid Background="#FFE5E5E5">
<TextBox HorizontalAlignment="Left" Height="23" Margin="143,129,0,0" TextWrapping="Wrap" Text="1" VerticalAlignment="Top" Width="29"/>
</Grid>
</TabItem>
<TabItem Name="Second" Header="TabItem" Visibility="Collapsed">
<Grid Background="#FFE5E5E5">
<TextBox HorizontalAlignment="Left" Height="23" Margin="195,90,0,0" TextWrapping="Wrap" Text="2" VerticalAlignment="Top" Width="29"/>
</Grid>
</TabItem>
</TabControl>
<Button Content="1" HorizontalAlignment="Left" Margin="191,359,0,0" VerticalAlignment="Top" Width="75" Click="Button_Click"/>
<Button Content="2" HorizontalAlignment="Left" Margin="484,379,0,0" VerticalAlignment="Top" Width="75" Click="Button_Click_1"/>
</Grid>

Dock a resizable wpf DataGrid at bottom of window

In a WPF project, I want to dock a DataGrid to the bottom of a window so that if the window resizes, I will be able to utilize more of the DataGrid. Like this:
How do I do that? All my DockPanel attempts have failed.
The current attempt is here:
<Window x:Class="Foo.SQLDialog"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:c="clr-namespace:Foo.Controls"
Title="test" ResizeMode="CanResize" Width="400" Height="400">
<StackPanel Orientation="Vertical" Height="Auto" Width="Auto">
<StackPanel Orientation="Vertical">
<Label Content="SQL" HorizontalAlignment="Left"/>
<TextBox Width="377" Height="100" Name="txtSQL"/>
<Button Content="Run SQL" Click="Button_Click_1" />
</StackPanel>
<Label Content="Result" HorizontalAlignment="Left"/>
<ScrollViewer Width="Auto" Height="180" DockPanel.Dock="Right,Bottom"
ScrollViewer.CanContentScroll="True"
ScrollViewer.VerticalScrollBarVisibility="Auto"
ScrollViewer.HorizontalScrollBarVisibility="Auto">
<DataGrid x:Name="dataResult" />
</ScrollViewer>
</StackPanel>
</Window>
The height of the scrollviewer+datagrid will not adapt however.
First of all, using DockPanel.Dock without having a DockPanel as a parent doesn't do much...
In my example I changed your root StackPanel to a DockPanel so it will work as you want.
I also used DockPanel.LastChildFill property which makes sure the last child of the DockPanel will get all the remaining space:
<DockPanel LastChildFill="True">
<StackPanel Orientation="Vertical" DockPanel.Dock="Top">
<Label Content="SQL" HorizontalAlignment="Left"/>
<TextBox Width="377" Height="100" Name="txtSQL"/>
<Button Content="Run SQL" Click="Button_Click_1" />
</StackPanel>
<Label Content="Result" HorizontalAlignment="Left" DockPanel.Dock="Top"/>
<ScrollViewer DockPanel.Dock="Bottom,Right"
ScrollViewer.CanContentScroll="True"
ScrollViewer.VerticalScrollBarVisibility="Auto"
ScrollViewer.HorizontalScrollBarVisibility="Auto">
<DataGrid x:Name="dataResult" />
</ScrollViewer>
</DockPanel>
Finally, to make it really stretch on all the remaining space, I removed the Height property you set, as this blocked it from stretching.
Not sure if useful or if i understand you question the right way but have you tried this:
<DataGrid DockPanel.Dock="Right, Bottom" VerticalAlignment="Bottom" HorizontalAlignment="Right" ></DataGrid>

How to make a WPF ComboBox to handle click on an overlying TextBlock?

I have a TextBlock which is over a ComboBox and I want the combobox popup (dropdown) apear when I click on it.
<Grid>
<ComboBox Name="tstcmb" Height="27" HorizontalAlignment="Left" Margin="29,92,0,0" VerticalAlignment="Top" Width="131" SelectedIndex="1" >
<ComboBoxItem>a</ComboBoxItem>
<ComboBoxItem>aaaa</ComboBoxItem>
</ComboBox>
<TextBlock Text="skdkdkdk" Background="Green" Height="16" HorizontalAlignment="Left" Margin="29,92,0,0" VerticalAlignment="Top" Width="131" />
</Grid>
Is it possible?
Set IsHitTestVisible="False"
<TextBlock IsHitTestVisible="False".../>
In that way the TextBlock doesn't intercept mouse clicks and allows them to be handled by the ComboBox underneath.

Can't get WPF ScrollViewer to work

I have a StackPanel and for some reason I can't get the content of the ScrollViewer on the very bottom to be scrollable, despite the fact that the internal height of the Frame clearly exceeds the bounds of the ScrollViewer. I previously had a Grid as the root container of the Window, but when I changed it to StackPanel the scrollbar no longer appears.
The only thing that seems to work is if I explicitly set the height of the ScrollViewer, but then it does not size with thw Window when it's resized.
Do I have to use a Grid?
Sorry if this is obvious; I'm relatively new to WPF.
Thanks in advance for any help!
<Window x:Class="MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" mc:Ignorable="d" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
d:DesignWidth="566" Width="719" >
<StackPanel VerticalAlignment="Stretch" >
<Menu HorizontalAlignment="Stretch" Name="Menu1" VerticalAlignment="Stretch" Width="Auto">
<MenuItem Header="_File" Name="MenuItem1">
<MenuItem Header="_Print" Name="MenuItem2" />
</MenuItem>
</Menu>
<Canvas x:Name="SearchCanvas" Width="681" Height="55">
<ComboBox Canvas.Left="6" Canvas.Top="0" Height="22" x:Name="cbLookupField" Width="302" Text="" SelectedIndex="0">
<ComboBoxItem Content="Reference Name" />
<ComboBoxItem Content="Matter" />
<ComboBoxItem Content="Client Loan Number" />
</ComboBox>
<TextBox KeyDown="tbLookup_KeyDown" Canvas.Left="6" Canvas.Top="28" Height="23" x:Name="tbLookup" Width="302" />
<Button Canvas.Left="314" Canvas.Top="27" Content="Search" Height="24" Name="btnSearch" Width="106" />
<ListView MouseDoubleClick="lvSearchResults_MouseDoubleClick"
ItemsSource="{Binding Tables[0]}"
Canvas.Left="-8" Canvas.Top="57" Height="129" Name="lvSearchResults" Width="697" Visibility="Hidden">
<ListView.View>
<GridView x:Name="gvResultsGridView"/>
</ListView.View>
</ListView>
</Canvas>
<ScrollViewer x:Name="ScrollViewer1" VerticalScrollBarVisibility="Visible">
<Frame Height="Auto" Source="Full Report.xaml" VerticalAlignment="Stretch" x:Name="Frame1" />
</ScrollViewer>
</StackPanel>
</Window>
The ScrollViewer in the bottom does not have a fixed height, and therefore because it's contained in a StackPanel, its height will be the height of the content, which in this case is the Frame height.
You can either set a fixed height for the ScrollViewer, or use a Grid instead of a StackPanel. In case you use a grid you should set a fixed height for the row in which the ScrollViewer will be located.
Hope it helps!

Scale usercontrol in wpf?

i have multiple items in my usercontrol. I put everything in a grid. But now i am trying, if the resolution of my screen changes, the window scales automatically. This just doesn't work.
I already used viewbox, but not with the wanted result.
This is my usercontrol:
<UserControl x:Class="NewWPFVragenBeheer.Maak_toets.Views.ChangeCourse"
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:converters="clr-namespace:NewWPFVragenBeheer.Converters"
mc:Ignorable="d" d:DesignHeight="200" d:DesignWidth="700"
>
<UserControl.Resources>
<XmlDataProvider x:Key="Vakken"
Source="C:\Users\Ruben\Desktop\Stage 26-04\stage_TFW\stage_TFW\NewWPFVragenBeheer\Data\Courses.xml"
XPath="/Courses/Course"
/>
<converters:RadioBoolToIntConverter x:Key="radioBoolToIntConverter" />
</UserControl.Resources>
<Viewbox Stretch="None">
<Grid >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="722*" />
<ColumnDefinition Width="254*" />
</Grid.ColumnDefinitions>
<Label Content="Maximale tijd:" Height="28" FontWeight="Bold" HorizontalAlignment="Left" Margin="12,28,0,0" Name="label1" VerticalAlignment="Top" Width="177" />
<TextBox Height="23" HorizontalAlignment="Left" Margin="215,30,0,0" Text="{Binding Path=MaxTime}" VerticalAlignment="Top" Width="145" />
<TextBox Height="23" HorizontalAlignment="Left" Margin="215,2,0,0" Text="{Binding Path=ExamName,UpdateSourceTrigger=PropertyChanged,Mode=TwoWay}" Name="textBox1" VerticalAlignment="Top" Width="145" />
<Label FontWeight="Bold" Content="Punten:" Height="28" HorizontalAlignment="Left" Margin="386,0,0,0" Name="label2" VerticalAlignment="Top" />
<TextBox Height="23" Text="{Binding Path=Score,UpdateSourceTrigger=PropertyChanged,Mode=TwoWay}" HorizontalAlignment="Left" Margin="567,2,0,0" Name="textBox2" VerticalAlignment="Top" Width="120" />
<Label Content="{Binding Path= FeedbackText, UpdateSourceTrigger=PropertyChanged,Mode=TwoWay}" Height="28" HorizontalAlignment="Right" Margin="0,153,527,0" Name="label3" VerticalAlignment="Top" Width="200" Foreground="#FFF50D0D" />
</Grid>
</Viewbox>
</UserControl>
this usercontrol is set in a window:
<Window x:Class="NewWPFVragenBeheer.MaakToetsDialog"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:view="clr-namespace:NewWPFVragenBeheer.Views"
Title="MaakToetsDialog"
WindowStyle ="SingleBorderWindow"
WindowState ="Maximized"
WindowStartupLocation="CenterScreen"
>
<view:MaakToetsView />
</Window>
¨please someone help.
Set the Grid to a fixed Width and Height, and set ViewBox.Stretch to Uniform. That should do it.
The correct answer likely is more complicated than the solution you seek, but I'll try to keep it short.
To do what you want, in my experience your best bet is to use a Grid as your primary initial element and then situate your controls within that Grid (or other Grids inside of it) and wrap the individual controls in ViewBoxes. After that tie the UserControl SizeChanged event to a method that forces the height and width of the UserControl to maintain an appropriate ratio.
That's the best way I have found to handle it on my WPF UIs.

Resources