Drag wpf window with thumb: can it be transparent? - wpf

I've been testing Blu and I noticed that I could drag the window. This window is transparent. I tried to do the same with a Thumb, but I don't know how to make it transparent. The rest of the window is transparent, but the thumb is not.
Is there any way to make the thumb transparent, or should I use another technique?
I use this event:
private void DragThumb_DragDelta(object sender, System.Windows.Controls.Primitives.DragDeltaEventArgs e)
{
Canvas.SetLeft(this, Canvas.GetLeft(this) + e.HorizontalChange);
Canvas.SetTop(this, Canvas.GetTop(this) + e.VerticalChange);
}
Thank you

You can turn a thumb control invisible with the Opacity attribute.
Opacity="1" (full visible)
or
Opacity="0" (not visible)
Sample from my application
<Thumb Name="myThumb"
Width="10"
Height="10"
DragDelta="onDragDelta"
DragStarted="onDragStarted"
DragCompleted="onDragCompleted"
Margin="5"
HorizontalAlignment="Right"
Opacity="1">
</Thumb>

Not sure if I understand your question correctly, but to drag a wpf window, all you need to type in the click event handler of a component on the form (or the form itsself) is:
this.DragMove();
There is no need to implement the dragging functionality yourself.
Update: small example: Create a window, place a button in it. Wire the MouseDown of the window and the Click of the button as:
private void Window_MouseDown(object sender, MouseButtonEventArgs e)
{
this.DragMove();
}
private void button1_Click(object sender, RoutedEventArgs e)
{
MessageBox.Show("hey");
}
Works perfectly, you can drag the window, and the button continues to work...

Related

WPF ListView and ScrollViewer hide MouseLeftButtonDown

To demostrate the problem I have this Xaml:
<DockPanel MouseLeftButtonDown="DockPanel_MouseLeftButtonDown" MouseLeftButtonUp="DockPanel_MouseLeftButtonUp">
<ListView>
<ListViewItem>ListViewItem</ListViewItem>
</ListView>
<TextBlock>TextBlock</TextBlock>
</DockPanel>
and the event handlers are :
private void DockPanel_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
Console.WriteLine("DockPanel_MouseLeftButtonDown");
}
private void DockPanel_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
Console.WriteLine("DockPanel_MouseLeftButtonUp");
}
When you run the app and click on the words TextBlock you get MouseDown fired followed by MouseUp. So far so good. But when you click on the words ListViewItem only MouseUp is fired. Same problem for ScrollViewer (List view includes it so I am guessing it's the same problem).
Does anybody know why and if this can be fixed.
By fixed I mean get it to fire not try to use another event or another mechanism all together.
First the problem:
As suspected the problem is in ScrollViewer: http://referencesource.microsoft.com/#PresentationFramework/Framework/System/Windows/Controls/ScrollViewer.cs,488ab4a977a015eb
protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e)
{
if (Focus())
e.Handled = true;
base.OnMouseLeftButtonDown(e);
}
As you can see it sets MouseButtonEventArgs.Handled to true which stops the bubbling of the event.
Now the solution - it is in the way you add the handler:
MyListView.AddHandler(
ListView.MouseLeftButtonDownEvent,
new MouseButtonEventHandler(ListView_MouseLeftButtonDown),
true);
Note the last parameter (true) it causes the handler to be invoked even if the EventArgs.Hanlded was set to true.
Then you can reset it:
private void ListView_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
e.Handled = false;
}
I had somewhat similar situation when ScrollViewer was blocking my MouseLeftButtonDown event. I had a content control wrapped into ScrollViewer:
<ScrollViewer VerticalScrollBarVisibility="Auto">
<ContentControl x:Name="Details" />
</ScrollViewer>
and this was inside of Popup which had a drag/drop behavior. So, because my behavior was not receiving this event, it did not work. When I added IsHitTestVisible="True" to ScrollViewer, my behavior started to work, but of course my ContentControl was not responding to any clicks. Then I saw this:
protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e)
{
if (Focus())
e.Handled = true;
base.OnMouseLeftButtonDown(e);
}
and tried to add Focusable="False" to exclude ScrollViewer from my click - it works. My behavior works and controls inside of ContentControl are getting all mouse events.
<ScrollViewer VerticalScrollBarVisibility="Auto" Focusable="False">
<ContentControl x:Name="Details" />
</ScrollViewer>
Hope it will help somebody.

How to click controls inside Popup with StaysOpen as False

I have a Popup with a ListView inside. I'd like to set StaysOpen as False so that it properly closes when I click away from the popup. However, this means that all mouse events are intercepted. As such, I don't get any mouse events inside my ListView.
Here's my current setup. I've removed all styling to make it easier to see what's going on.
<Popup Name="puSearchResults" StaysOpen="False"
AllowsTransparency="True"
LostFocus="puSearchResults_LostFocus"
LostKeyboardFocus="puSearchResults_LostKeyboardFocus"
LostMouseCapture="puSearchResults_LostMouseCapture" >
<ListView Name="lvSearchResults"
MouseLeftButtonDown="lbSearchResults_MouseLeftButtonDown"
SelectionChanged="lvSearchResults_SelectionChanged"/>
</Popup>
In this case, MouseLeftButtonDown only works if I set StaysOpen to True, but then the Popup doesn't disappear if I click away.
Ideas?
I would add mouse events to the ListView or to the objects in your ListView's data templete.
Then you could do this:
private void lvSearchResults_MouseEnter(object sender, MouseEventArgs e)
{
puSearchResults.StaysOpen = true;
}
private void lvSearchResults_MouseLeave(object sender, MouseEventArgs e)
{
puSearchResults.StaysOpen = false;
}
EDIT
Similar question that should help: Close Wpf Popup On click of item of its own control template

Prevent hyperlink Click event from bubbling up

I'm designing a windows Phone app. I have a Hyperlink object in a RichTextBox, in a Grid. The Grid had a Tap event, and the Hyperlink has a Click event.
Clicking the Hyperlink also raises the parent Grid's Tap event. How can I prevent this?
I would use e.Handled in the Click handler, but RoutedEventArgs do not have a Handled property in Silverlight for Windows Phone... I also tried walking the logical tree to look for the original source, but the click appears to originate from a MS.Internal.RichTextBoxView control (e.OriginalSource)...
I don't think there is any good way from within the Click handler itself. The following state management can work though:
XAML:
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0" Tap="ContentPanel_Tap_1">
<RichTextBox Tap="RichTextBox_Tap_1">
<Paragraph>
fdsfdfdf
<Hyperlink Click="Hyperlink_Click_1">fdsfdsfsaf</Hyperlink>
fsdfsdfa
</Paragraph>
</RichTextBox>
</Grid>
and the code:
bool RtbTapHandled = false;
private void Hyperlink_Click_1(object sender, RoutedEventArgs e)
{
System.Diagnostics.Debug.WriteLine("Hyperlink");
RtbTapHandled = true;
}
private void RichTextBox_Tap_1(object sender, System.Windows.Input.GestureEventArgs e)
{
if (RtbTapHandled)
{
e.Handled = true;
}
RtbTapHandled = false;
System.Diagnostics.Debug.WriteLine("RTB_Tap");
}
private void ContentPanel_Tap_1(object sender, System.Windows.Input.GestureEventArgs e)
{
System.Diagnostics.Debug.WriteLine("Content_Tap");
}
In this case if you click on the RichTextBox you'll get callbacks from both RichTextBox_Tap_1 and ContentPanel_Tap_1, but if you click on the Hyperlink you'll get Hyperlink_Click_1 and RichTextBox_Tap_1 though it'll be handled at that level and stopped.

Cant drag and move a WPF Form

I design a WPF form with Window Style=None. So I Cannot see the drag bar in the form. How can I move the Form with WindowStyle=None Property?
I am using a main window to hold pages (creating a navigation style program), and in the code behind of my main window, I inserted this...
protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e)
{
base.OnMouseLeftButtonDown(e);
// Begin dragging the window
this.DragMove();
}
... and it works like a charm. This is with windowstyle=none. Its nice in the sense that you can click anywhere on the app and move it instead of just being limited to a top bar.
See this question.
Basically you use the Window.DragMove method for this.
In our application we have Windows with WindowStyle set to "none", we implemented the functionality to drag the Window, but only from the header rather than from any point in the Window. We did this by adding a Border as a header, then adding a Thumb to fill the entire Border. We then handle the DragDelta method on the Thumb in the code-behind for the Window.
<Border
Name="headerBorder"
Width="Auto"
Height="50"
VerticalAlignment="Top"
CornerRadius="5,5,0,0"
DockPanel.Dock="Top"
Background="{StaticResource BackgroundBrush}"
BorderThickness="1,1,1,1"
BorderBrush="{StaticResource BorderBrush}">
<Grid>
<Thumb
x:Name="headerThumb"
Opacity="0"
Background="{x:Null}"
Foreground="{x:Null}"
DragDelta="headerThumb_DragDelta"/>
</Grid>
</Border>
Then in the code-behind we have the following event handler...
private void headerThumb_DragDelta(object sender, DragDeltaEventArgs e)
{
Left = Left + e.HorizontalChange;
Top = Top + e.VerticalChange;
}
I don't know if this is any better than the other method, it's just the way we did it.
either inside the windows on load function or inside the grid's on load function use a deligate to trigger the DragMove() method on Mouse Click
private void Grid_Loaded(object sender, RoutedEventArgs e)
{
this.MouseLeftButtonDown += delegate{DragMove();};
}
If you simply add this.DragMove(); and you are using Bing Maps, then you will get some frustrating behavior when trying to pan the map.
Using TabbyCool's answer was a good solution however, you can not drag the window against the top of the screen to maximise it.
My solution was just checking that the position.Y of my click relative to my top bar grid was less than a suitable amount.
protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e)
{
base.OnMouseLeftButtonDown(e);
Point pt = e.GetPosition(topBar);
Debug.WriteLine(pt.Y);
if (pt.Y < topBar.ActualHeight)
{
DragMove();
}
}

Slider MouseLeftButtonDown Doesn't Work?

When trying to use a Slider control I'd like to listen to the MouseLeftButtonDown and MouseLeftButtonUp. I have handlers set up for both events. The MouseLeftButtonUp works as expected. MouseLeftButtonDown is not raised at all.
Any ideas why?
I've done a bit of googling and it seems that the WPF doesn't fire either. One of the solutions (in this post) was to use the Preview version of the events which is something silverlight doesn't support.
Is there any simple solution to this that I'm not seeing?
Thanks
J
It happens because Slider handles mouse down/up events. Internally its implemented as two RepeatButtons and a thumb in the middle. When you click on left or right side of the slider your mouse events are handled by RepeatButtons, and you don't get them.
If you still want to handle handled event you can use AddHandler() method. Here is Silverlight example:
XAML
<Slider Width="100"
VerticalAlignment="Top"
Minimum="0"
Maximum="100"
Name="sl" />
C#
public partial class MainPage : UserControl
{
public MainPage()
{
InitializeComponent();
sl.AddHandler(MouseLeftButtonDownEvent, new MouseButtonEventHandler(Slider_MouseLeftButtonDown), true);
sl.AddHandler(MouseLeftButtonUpEvent, new MouseButtonEventHandler(Slider_MouseLeftButtonUp), true);
}
private void Slider_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
}
private void Slider_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
}
}
In WPF situation is almost same (small differences in names).

Resources