Reputation: 75
i have the Problem that i have a Menu inside a Stackpanel, that is inside of an ScrollViewer. Now it's possible to scroll horizontally even if the Horizontally Scrollbar is Hidden. The Mainproblem now is, that i can't make a Clickevent for the buttons. It seems that my Scroll Event blocks something under it.
The XAML Code
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="200"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="200"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="110"/>
<RowDefinition Height="*"/>
<RowDefinition Height="100"/>
</Grid.RowDefinitions>
<Rectangle x:Name="rectangel1" Grid.RowSpan="3">
<Rectangle.Fill>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#FF0036A0" Offset="0.003"/>
<GradientStop Color="#FFE9EDFF" Offset="1"/>
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>
<Grid Grid.Column="1" Grid.ColumnSpan="2">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="20"/>
<ColumnDefinition Width="750"/>
<ColumnDefinition Width="20"/>
</Grid.ColumnDefinitions>
<ScrollViewer x:Name="scrollviewer1" Grid.Column="1" Grid.ColumnSpan="2"
HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Disabled"
PanningMode="HorizontalOnly"
MouseUp="UIElement_OnMouseUp"
PreviewMouseLeftButtonDown="UIElement_OnPreviewMouseLeftButtonDown"
PreviewMouseMove="UIElement_OnPreviewMouseMove" Cursor="Hand">
<StackPanel Orientation="Horizontal" Grid.Column="1" Grid.ColumnSpan="1">
<Grid Width="87" Height="90" Margin="10,10,10,10">
<Rectangle x:Name="btn1" Fill="#FFF39999" RadiusX="10" RadiusY="10" />
<Label Content="No Btn 1" HorizontalAlignment="Center" VerticalAlignment="Bottom" FontSize="16" FontWeight="Bold"/>
</Grid>
<Grid Width="87" Height="90" Margin="10,10,10,10">
<Rectangle x:Name="btn2" Fill="#FFF39999" RadiusX="10" RadiusY="10" />
<Label Content="No Btn 2" HorizontalAlignment="Center" VerticalAlignment="Bottom" FontSize="16" FontWeight="Bold"/>
</Grid>
<!--<Grid Width="87" Height="90" Margin="10,10,10,10">
<Rectangle x:Name="btn3" Fill="#FFF39999" RadiusX="10" RadiusY="10" />
<Label Content="Station 3" HorizontalAlignment="Center" VerticalAlignment="Bottom" FontSize="16" FontWeight="Bold"/>
</Grid>-->
<Grid Width="87" Height="90" Margin="10,10,10,10">
<Button x:Name="btn3" Content="Station 3" Click="btn3_Click" Style="{DynamicResource ButtonStyle1}" >
<Button.Resources>
<Style x:Key="ButtonFocusVisual">
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate>
<Rectangle Margin="2" SnapsToDevicePixels="true" Stroke="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" StrokeThickness="1" StrokeDashArray="1 2"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<LinearGradientBrush x:Key="ButtonNormalBackground" EndPoint="0,1" StartPoint="0,0">
<GradientStop Color="#F3F3F3" Offset="0"/>
<GradientStop Color="#EBEBEB" Offset="0.5"/>
<GradientStop Color="#DDDDDD" Offset="0.5"/>
<GradientStop Color="#CDCDCD" Offset="1"/>
</LinearGradientBrush>
<SolidColorBrush x:Key="ButtonNormalBorder" Color="#FF707070"/>
<Style x:Key="ButtonStyle1" TargetType="{x:Type Button}">
<Setter Property="FocusVisualStyle" Value="{StaticResource ButtonFocusVisual}"/>
<Setter Property="Background" Value="{StaticResource ButtonNormalBackground}"/>
<Setter Property="BorderBrush" Value="{StaticResource ButtonNormalBorder}"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
<Setter Property="HorizontalContentAlignment" Value="Center"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="Padding" Value="1"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Grid>
<Rectangle Fill="#FFFFA6A6" RadiusY="10" RadiusX="10"/>
<Label x:Name="label" Content="BUTTON" HorizontalAlignment="Center" VerticalAlignment="Bottom" FontSize="16" FontWeight="Bold"/>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsKeyboardFocused" Value="true"/>
<Trigger Property="ToggleButton.IsChecked" Value="true"/>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Foreground" Value="#ADADAD"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Button.Resources>
</Button>
</Grid>
<Grid Width="87" Height="90" Margin="10,10,10,10">
<Rectangle x:Name="btn4" Fill="#FFF39999" RadiusX="10" RadiusY="10" />
<Label Content="No Btn 4" HorizontalAlignment="Center" VerticalAlignment="Bottom" FontSize="16" FontWeight="Bold"/>
</Grid>
<Grid Width="87" Height="90" Margin="10,10,10,10">
<Rectangle x:Name="btn5" Fill="#FFF39999" RadiusX="10" RadiusY="10" />
<Label Content="No Btn 5" HorizontalAlignment="Center" VerticalAlignment="Bottom" FontSize="16" FontWeight="Bold"/>
</Grid>
<Grid Width="87" Height="90" Margin="10,10,10,10">
<Rectangle x:Name="btn6" Fill="#FFF39999" RadiusX="10" RadiusY="10" />
<Label Content="No Btn 6" HorizontalAlignment="Center" VerticalAlignment="Bottom" FontSize="16" FontWeight="Bold"/>
</Grid>
<Grid Width="87" Height="90" Margin="10,10,10,10">
<Rectangle x:Name="btn7" Fill="#FFF39999" RadiusX="10" RadiusY="10" />
<Label Content="No Btn 7" HorizontalAlignment="Center" VerticalAlignment="Bottom" FontSize="16" FontWeight="Bold"/>
</Grid>
<Grid Width="87" Height="90" Margin="10,10,10,10">
<Rectangle x:Name="btn8" Fill="#FFF39999" RadiusX="10" RadiusY="10" />
<Label Content="No Btn 8" HorizontalAlignment="Center" VerticalAlignment="Bottom" FontSize="16" FontWeight="Bold"/>
</Grid>
<Grid Width="87" Height="90" Margin="10,10,50,10">
<Button x:Name="btn9" Content="Station 9" Click="btn9_Click" Style="{DynamicResource ButtonStyle1}" >
<Button.Resources>
<Style x:Key="ButtonFocusVisual">
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate>
<Rectangle Margin="2" SnapsToDevicePixels="true" Stroke="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" StrokeThickness="1" StrokeDashArray="1 2"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<LinearGradientBrush x:Key="ButtonNormalBackground" EndPoint="0,1" StartPoint="0,0">
<GradientStop Color="#F3F3F3" Offset="0"/>
<GradientStop Color="#EBEBEB" Offset="0.5"/>
<GradientStop Color="#DDDDDD" Offset="0.5"/>
<GradientStop Color="#CDCDCD" Offset="1"/>
</LinearGradientBrush>
<SolidColorBrush x:Key="ButtonNormalBorder" Color="#FF707070"/>
<Style x:Key="ButtonStyle1" TargetType="{x:Type Button}">
<Setter Property="FocusVisualStyle" Value="{StaticResource ButtonFocusVisual}"/>
<Setter Property="Background" Value="{StaticResource ButtonNormalBackground}"/>
<Setter Property="BorderBrush" Value="{StaticResource ButtonNormalBorder}"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
<Setter Property="HorizontalContentAlignment" Value="Center"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="Padding" Value="1"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Grid>
<Rectangle Fill="#FFFFA6A6" RadiusY="10" RadiusX="10"/>
<Label x:Name="label" Content="Button 9" HorizontalAlignment="Center" VerticalAlignment="Bottom" FontSize="16" FontWeight="Bold"/>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsKeyboardFocused" Value="true"/>
<Trigger Property="ToggleButton.IsChecked" Value="true"/>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Foreground" Value="#ADADAD"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Button.Resources>
</Button>
</Grid>
</StackPanel>
</ScrollViewer>
<Rectangle x:Name="rectlinks" Grid.Column="0" Fill="#FFFF7676" MouseEnter="rectlinks_MouseEnter" />
<Rectangle x:Name="rectrechts" Grid.Column="2" MouseEnter="rectrechts_MouseEnter" Fill="#FFFF7474" />
</Grid>
<Label x:Name="label1" Content="Wert"/>
<Label x:Name="label2" Content="mehr" Margin="0,50,0,0"/>
</Grid>
The C# Code
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace ScrollMenue
{
/// <summary>
/// Interaktionslogik für MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
private double hOff;
public MainWindow()
{
InitializeComponent();
}
private void rectrechts_MouseEnter(object sender, MouseEventArgs e)
{
label1.Content = "rechts";
scrollviewer1.LineRight();
}
private void rectlinks_MouseEnter(object sender, MouseEventArgs e)
{
if (rectlinks.IsMouseOver == true)
{
scrollviewer1.ScrollToHorizontalOffset(scrollviewer1.HorizontalOffset + 10);
label1.Content = "links";
scrollviewer1.LineLeft();
}
}
private Point scrollMousePoint;
private void UIElement_OnMouseUp(object sender, MouseButtonEventArgs e)
{
scrollviewer1.ReleaseMouseCapture();
}
private void UIElement_OnPreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
scrollviewer1.CaptureMouse();
scrollMousePoint = e.GetPosition(scrollviewer1);
hOff = scrollviewer1.HorizontalOffset;
}
private void UIElement_OnPreviewMouseMove(object sender, MouseEventArgs e)
{
if (scrollviewer1.IsMouseCaptured)
{
scrollviewer1.ScrollToHorizontalOffset(hOff + (scrollMousePoint.X - e.GetPosition(scrollviewer1).X));
}
}
private void btn9_Click(object sender, RoutedEventArgs e)
{
label2.Content = "Click";
}
private void btn3_Click(object sender, RoutedEventArgs e)
{
label2.Content = "Click";
}
}
}
Upvotes: 4
Views: 6380
Reputation: 75
So now i found the solution i wanted, with help from JohnChris and an other good programmer :D thanks to all :D
Must add a reference to the project, UIAutomationProvider.dll and two using statements, using System.Windows.Automation.Peers and System.Windows.Automation.Provider, these allow usage of Invoke Provider and Peers
The XAML Code:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="200"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="200"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="110"/>
<RowDefinition Height="*"/>
<RowDefinition Height="100"/>
</Grid.RowDefinitions>
<Rectangle Name="rectangel1" Grid.RowSpan="3">
<Rectangle.Fill>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#FF0036A0" Offset="0.003"/>
<GradientStop Color="#FFE9EDFF" Offset="1"/>
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>
<Grid Grid.Column="1" Grid.ColumnSpan="2">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="20"/>
<ColumnDefinition Width="750"/>
<ColumnDefinition Width="20"/>
</Grid.ColumnDefinitions>
<ScrollViewer Name="scrollviewer1" Grid.Column="1" Grid.ColumnSpan="2"
HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Disabled"
PanningMode="HorizontalOnly"
MouseUp="UIElement_OnMouseUp"
PreviewMouseLeftButtonDown="UIElement_OnPreviewMouseLeftButtonDown"
PreviewMouseMove="UIElement_OnPreviewMouseMove"
>
<StackPanel Orientation="Horizontal" Grid.Column="1" Grid.ColumnSpan="1">
<Grid Width="87" Height="90" Margin="10,10,10,10">
<Rectangle Name="btn1" Fill="#FFF39999" RadiusX="10" RadiusY="10" />
<Label Content="Station 1" HorizontalAlignment="Center" VerticalAlignment="Bottom" FontSize="16" FontWeight="Bold"/>
</Grid>
<Grid Width="87" Height="90" Margin="10,10,10,10">
<Rectangle Name="btn2" Fill="#FFF39999" RadiusX="10" RadiusY="10" />
<Label Content="Station 2" HorizontalAlignment="Center" VerticalAlignment="Bottom" FontSize="16" FontWeight="Bold"/>
</Grid>
<Grid Width="87" Height="90" Margin="10,10,10,10">
<Rectangle Name="btn3" Fill="#FFF39999" RadiusX="10" RadiusY="10" />
<!--<Label Content="Station 3" HorizontalAlignment="Center" VerticalAlignment="Bottom" FontSize="16" FontWeight="Bold"/>-->
<Button Name="BtnFoo" Click="ButtonBase_OnClick">Foo!</Button>
</Grid>
<Grid Width="87" Height="90" Margin="10,10,10,10">
<Rectangle Name="btn4" Fill="#FFF39999" RadiusX="10" RadiusY="10" />
<Label Content="Station 4" HorizontalAlignment="Center" VerticalAlignment="Bottom" FontSize="16" FontWeight="Bold"/>
</Grid>
<Grid Width="87" Height="90" Margin="10,10,10,10">
<Rectangle Name="btn5" Fill="#FFF39999" RadiusX="10" RadiusY="10" />
<Label Content="Station 5" HorizontalAlignment="Center" VerticalAlignment="Bottom" FontSize="16" FontWeight="Bold"/>
</Grid>
<Grid Width="87" Height="90" Margin="10,10,10,10">
<Rectangle Name="btn6" Fill="#FFF39999" RadiusX="10" RadiusY="10" />
<Label Content="Station 6" HorizontalAlignment="Center" VerticalAlignment="Bottom" FontSize="16" FontWeight="Bold"/>
</Grid>
<Grid Width="87" Height="90" Margin="10,10,10,10">
<Rectangle Name="btn7" Fill="#FFF39999" RadiusX="10" RadiusY="10" />
<Label Content="Station 7" HorizontalAlignment="Center" VerticalAlignment="Bottom" FontSize="16" FontWeight="Bold"/>
</Grid>
<Grid Width="87" Height="90" Margin="10,10,50,10">
<Rectangle Name="btn8" Fill="#FFF39999" RadiusX="10" RadiusY="10" />
<Label Content="Station 8" HorizontalAlignment="Center" VerticalAlignment="Bottom" FontSize="16" FontWeight="Bold"/>
</Grid>
</StackPanel>
</ScrollViewer>
<Rectangle Name="rectlinks" Grid.Column="0" Fill="#FFFF7676" MouseEnter="rectlinks_MouseEnter" />
<Rectangle Name="rectrechts" Grid.Column="2" MouseEnter="rectrechts_MouseEnter" Fill="#FFFF7474" />
</Grid>
<Label Name="label1" Content="Wert"/>
<Label Name="label2" Content="mehr" Margin="0,50,0,0"/>
</Grid>
The C# Code:
namespace ScrollMenue
{
/// <summary>
/// Interaktionslogik für MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
private double hOff;
public MainWindow()
{
InitializeComponent();
}
private void rectrechts_MouseEnter(object sender, MouseEventArgs e)
{
//label1.Content = "rechts";
//scrollviewer1.LineRight();
}
private void rectlinks_MouseEnter(object sender, MouseEventArgs e)
{
//if (rectlinks.IsMouseOver == true)
//{
// scrollviewer1.ScrollToHorizontalOffset(scrollviewer1.HorizontalOffset + 10);
// label1.Content = "links";
// scrollviewer1.LineLeft();
//}
}
private Point scrollMousePoint;
private bool drag;
private void UIElement_OnMouseUp(object sender, MouseButtonEventArgs e)
{
scrollviewer1.ReleaseMouseCapture();
if (IsMouseOverControl(BtnFoo) && !drag)
{
var peer = new ButtonAutomationPeer(BtnFoo);
var invokeProv = peer.GetPattern(PatternInterface.Invoke) as IInvokeProvider;
invokeProv?.Invoke();
}
drag = false;
}
private void UIElement_OnPreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
scrollMousePoint = e.GetPosition(scrollviewer1);
hOff = scrollviewer1.HorizontalOffset;
drag = false;
scrollviewer1.CaptureMouse();
}
private void UIElement_OnPreviewMouseMove(object sender, MouseEventArgs e)
{
if (scrollviewer1.IsMouseCaptured)
{
var moveTo = scrollMousePoint.X - e.GetPosition(scrollviewer1).X;
if (Math.Abs(moveTo ) > 1)
{
drag = true;
scrollviewer1.ScrollToHorizontalOffset(hOff + moveTo);
}
}
}
private void ButtonBase_OnClick(object sender, RoutedEventArgs e)
{
MessageBox.Show("Click");
}
private bool IsMouseOverControl(UIElement control)
{
var mousePos = Mouse.GetPosition(control);
var size = control.RenderSize;
if (mousePos.X < 0 || mousePos.X > size.Width ||
mousePos.Y < 0 || mousePos.Y > size.Height)
{
return false;
}
return true;
}
}
}
Upvotes: 1
Reputation: 1360
I found your solution,
I just did it for one button, but you can do for all,
private void UIElement_OnPreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
if (e.Source == btn3)
{ btn3_Click(sender, e); }
scrollMousePoint = e.GetPosition(scrollviewer1);
hOff = scrollviewer1.HorizontalOffset;
scrollviewer1.CaptureMouse();
}
private void btn9_Click(object sender, RoutedEventArgs e)
{
label2.Content = "i AM WORKING"; //You can press and still scroll
}
UPDATE:
From the comments you say you now want to not trigger the button when touched as you may just want to scroll, you need to implement some type of logic such as a hold gesture , here is a post on that
Do WPF have Touch-and-Hold gesture?
UPDATE 2:
Yay I did it, and it's a really simple solution,
add another handler in xaml for PreviewMouseLeftButtonUp then in code behind(c#) do this:
private DateTime mouseTimer;
private void UIElement_OnPreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
mouseTimer = DateTime.Now;
scrollviewer1.CaptureMouse();
scrollMousePoint = e.GetPosition(scrollviewer1);
hOff = scrollviewer1.HorizontalOffset;
}
private void scrollviewer1_PreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
TimeSpan difference = DateTime.Now - mouseTimer;
if (difference.TotalSeconds < 1)
{
btn3_Click(sender, e);
}
else
return;
}
So now , if its a Click, it opens, but you hold the click, it will just scroll, dateTime usage is awesome there
Upvotes: 0