wpf - how can I hit test the scrollbars in the scrollviewer? - wpf

Can someone please tell me how to hit test the scrollbars of a scrollviewer in WPF?
Thanks,
Andy
<Window x:Class="WpfApplication1.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300">
<StackPanel>
<ScrollViewer Name="myScrollViewer" Width="280" Height="200" MouseMove="ScrollViewer_MouseMove" >
</ScrollViewer>
<TextBox Name="myTextBox"></TextBox>
</StackPanel>
</Window>
Code behind ...
using System.Windows.Input;
namespace WpfApplication1
{
/// <summary>
/// Interaction logic for Window1.xaml
/// </summary>
public partial class Window1
{
public Window1()
{
InitializeComponent();
}
private void ScrollViewer_MouseMove(object sender, MouseEventArgs e)
{
myTextBox.Text = e.GetPosition(myScrollViewer).X + "," + e.GetPosition(myScrollViewer).Y;
}
}
}

With VisualTreeHelper.HitTest, the MouseEventArgs is relatif to the scrollviewer, so the first parameter is your ScrollViewer.
Then use PointHitTestParameter with the coordinate of the MouseEventArgs.

Related

WPF Radio Buttons

I am creating Radio button on Visual Studio and I am having a trouble with Binding
This is my button:
<RadioButton VericalAlignment="Center" GroupName="group1" Content="name"></RadioButton>
I want that if the button was selected then the value of {"someString " + Content Value} will be bind
to SomeClass.variable
is something like this possible?
Thank you!
Something like this should work:
XAML:
<Window x:Class="StackOverflowRadioButton.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:StackOverflowRadioButton"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid Margin="81,36,-81,-36">
<RadioButton Content="RadioButton" HorizontalAlignment="Left" Margin="111,135,0,0" VerticalAlignment="Top"
Name="myRadioButton" Checked="myRadioButton_Checked"/>
</Grid>
CS file:
using System.Windows;
namespace StackOverflowRadioButton
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public string someVariable;
public MainWindow()
{
InitializeComponent();
}
private void myRadioButton_Checked(object sender, RoutedEventArgs e)
{
someVariable = "someString " + myRadioButton.IsChecked;
}
}
}

wpf - window freezes

Parent window freezes when I open a window on click of a button. It works properly again if I minimize and maximize parent window again.
System configuration
Windows 7, 64 bit OS.
.Net framework 3.5 SP1
Visual studio express 2008
Following is the simple application where I can reproduce this issue.
Window1.xaml
<Window x:Class="WpfApplication1.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300">
<StackPanel>
<TextBox Width="200"/>
<Button Content="click" Click="Button_Click"/>
</StackPanel>
</Window>
Window1.xaml.cs
namespace WpfApplication1 {
/// <summary>
/// Interaction logic for Window1.xaml
/// </summary>
public partial class Window1 : Window {
public Window1() {
InitializeComponent();
}
private void Button_Click(object sender, RoutedEventArgs e) {
(new Window2()).ShowDialog();
}
}
}
Window2.xaml
<Window x:Class="WpfApplication1.Window2"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window2" Height="300" Width="300" WindowStyle="ToolWindow">
<Grid>
</Grid>
</Window>
It works fine if I remove WindowStyle="ToolWindow" !!!!!!
App.xaml
<Application x:Class="WpfApplication1.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="Window1.xaml">
<Application.Resources>
</Application.Resources>
</Application>
The call to ShowDialog() is blocking your GUI thread.
See this question for alternative approaches which don't block the main thread.
Use Show instead of ShowDialog which opens a window in Modal mode
If you use ShowDialog() try set Window1 as Owner for Window2:
Window2 w = new Window2 { Owner = this };
w.ShowDialog();
Show instead of show dialog will work, but maybe you intention was something more like a child window see http://wpftoolkit.codeplex.com/wikipage?title=ChildWindow&referringTitle=Home for details.

Why my binding don't work on a ObservableCollection

Hello I am trying to bind a ItemsSource to a ObservableCollection. It seems the ObservableCollection is not seen by the IntelliSense event if the ObservableCollection is public.
Do I have the declare something in XAML to make it visible ? Like in Window.Ressources.
My XAML code
<Window x:Class="ItemsContainer.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<StackPanel Orientation="Horizontal">
<ListBox ItemsSource="{Binding StringList}" />
</StackPanel> </Window>
My C# code
using System.Collections.ObjectModel;
using System.Windows;
namespace ItemsContainer
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
private ObservableCollection<string> stringList = new ObservableCollection<string>();
public ObservableCollection<string> StringList
{
get
{
return this.stringList;
}
set
{
this.stringList = value;
}
}
public MainWindow()
{
InitializeComponent();
this.stringList.Add("One");
this.stringList.Add("Two");
this.stringList.Add("Three");
this.stringList.Add("Four");
this.stringList.Add("Five");
this.stringList.Add("Six");
}
}
}
To the best of my knowledge that binding should bind to the property StringList of the current
DataContext, which is MainWindow.
Thanks for any pointer.
Edit:
This worked for me in XAML
<Window x:Class="ItemsContainer.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<StackPanel Orientation="Horizontal">
<ListBox ItemsSource="{Binding RelativeSource={RelativeSource AncestorType=Window},Path=StringList}" />
</StackPanel>
</Window>
The DataContext does not default to the MainWindow, you'd have to explicitly set that. Like so:
public MainWindow() {
InitializeComponent();
this.stringList.Add("One");
this.stringList.Add("Two");
this.stringList.Add("Three");
this.stringList.Add("Four");
this.stringList.Add("Five");
this.stringList.Add("Six");
this.DataContext = this;
}

Keep focus on another control while selecting items in a ListBox

I have TextBox which should always be in focus.
At the same time I have as list box.
When user clicks on certain item in this listobox the item clicked gets focus.
I tried to set Focusable="false" for each ListBoxItem in my ListBox but in this case no item can be selected.
I found following code using dotPeek:
private void HandleMouseButtonDown(MouseButton mouseButton)
{
if (!Selector.UiGetIsSelectable((DependencyObject) this) || !this.Focus())
return;
...
}
Is there any way to solve my problem?
You could handle PreviewMouseDown on the ListBoxItems and mark the event as Handled which will stop the focus being transferred.
You can set e.Handled = true because MouseButtonEventArgs is a RoutedEventArgs.
This demo works to keep focus on the TextBox:
XAML
<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="350"
Width="525">
<StackPanel FocusManager.FocusedElement="{Binding ElementName=textBox}">
<TextBox x:Name="textBox" />
<ListBox x:Name="listBox">
<ListBoxItem PreviewMouseDown="ListBoxItem_PreviewMouseDown">1</ListBoxItem>
<ListBoxItem PreviewMouseDown="ListBoxItem_PreviewMouseDown">2</ListBoxItem>
<ListBoxItem PreviewMouseDown="ListBoxItem_PreviewMouseDown">3</ListBoxItem>
</ListBox>
</StackPanel>
</Window>
Code Behind
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
namespace WpfApplication1
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void ListBoxItem_PreviewMouseDown(object sender, MouseButtonEventArgs e)
{
var item = sender as ListBoxItem;
if (item == null) return;
listBox.SelectedItem = item;
e.Handled = true;
}
}
}

Incorrect pixel coordinates

I am using the following code to get pixel coordinates of the mouse position.
private void canvas_MouseMove(object sender, MouseEventArgs e)
{
startPoint = e.GetPosition(this);
}
However, if the user uses the scroll bar to move down a bit then this code does not work. I get the wrong coordinates and the object does not get drawn under the mouse position. Any ideas what going on here?
What you're doing should (more or less) work. You might have some problem with exactly which MouseMove event you are listening to, though.
Here is a sample app that demonstrates the desired behavior.
The XAML:
<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="350" Width="525">
<Grid Margin="12">
<ScrollViewer Name="scrollViewer"
HorizontalScrollBarVisibility="Auto"
VerticalScrollBarVisibility="Auto"
MouseMove="ScrollViewer_MouseMove">
<Canvas Name="canvas" Width="800" Height="600" />
</ScrollViewer>
</Grid>
</Window>
The code-behind:
using System.Windows;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Shapes;
namespace WpfApplication1
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void ScrollViewer_MouseMove(object sender, MouseEventArgs e)
{
Point mousePosition = e.GetPosition(canvas);
var rectangle = new Rectangle
{
RenderTransform = new TranslateTransform(
mousePosition.X,
mousePosition.Y),
Stroke = Brushes.Black,
};
canvas.Children.Add(rectangle);
}
}
}
The key here is I bound the MouseMove event to the ScrollViewer, and checked the position of the Canvas.

Resources