locked
WPF Grid MouseLeftButtonDown, MouseLeftButtonUp Events Not Firing RRS feed

  • Question

  • Hi,

    I have a Small Trouble with my app i am working on.....

    1. I have a Grid with Image Buttons in it.
    2. I have some images on left menu
    so.. When i drag and Drop images onto Buttons within Grid, the Images Should Snap In and Place on Button.

    I have designed Grid with that Image Buttons , and the Snap in Feature too.

    Now My question was i wrote the Snap In Feature on Mouse Enter event of a Button.
    But i want to Write the same logic in MouseLeftButtonUp event of a button. When i write the Event it is not firing up.

    Please advice

    Thanks,

    San
    Monday, March 15, 2010 11:24 PM

Answers

  • Hi Starterkit,

    Based on my understanding, you want to drag and drop an image from one place to the button by mouse left button. This feature is same with the content of a thread posted by you before: http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/8d858942-fef1-4b6b-9024-a86494d52e6a. Is it right?

    I performed a test based on your description and Jarrey's code. There may be two cases to your issue.

    1. When we click down the mouse left button on the source object and Up it on another object (like Button), the target object could not fire up the MouseLeftButtonUp event. Because of the Button element converts a MouseDown event followed by a MouseUp event into a Click event. It halts the handle (by set the Handled flag). You could do a simple test, add a MouseLeftButtonUp event to a button, and you click this button. The MouseLeftButtonUp event will not be handled.

    One solution, we can use preview event to handle your request in the Button: PreviewMouseLeftButtonUp

    Thanks to Jarrey’s code on that thread, below is my code modified from Jarrey's code:

    <Image x:Name="moveImg" Width="50" Height="50" Opacity="0.5" Visibility="Hidden"  Panel.ZIndex="11">
    ......
    <Button Canvas.Left="75" Canvas.Top="96" PreviewMouseLeftButtonUp="rec_MouseLeftButtonUp" Panel.ZIndex="12">
    	<Grid>
    		<Grid.ColumnDefinitions>
    			<ColumnDefinition/>
    			<ColumnDefinition/>
    		</Grid.ColumnDefinitions>
    		<Rectangle Grid.Column="0" Width="100" Height="50" x:Name="rec" Stroke="Black"/>
    		<TextBlock Grid.Column="1" VerticalAlignment="Center" >Click</TextBlock>
    	</Grid>
    </Button>
    ......


    2. If the Button's ZIndex is less than the MovingImage's, it cannot fire the MouseLeftButtonUp on the Button. Because the pointer dose not contact with the Button directly when we release the left mouse button.

    I suggest that change the drag style like Windows drag style.  We can use a special cursor when we drag an object on the Button. Below is my code based on Jarrey's code:

    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" MouseLeftButtonUp="Window_MouseLeftButtonUp" MouseMove="Window_MouseMove">
        
        <Window.Resources>
            <BitmapImage x:Key="imageRes" UriSource="......"/>
        </Window.Resources>
        <Canvas x:Name="canvas" >
            <TextBlock HorizontalAlignment="Center" Height="15.96" Canvas.Left="52" Canvas.Top="12" Width="39">Source:</TextBlock>
            <Image x:Name="img" Source="{StaticResource imageRes}" Width="50" Height="50" MouseLeftButtonDown="img_MouseLeftButtonDown" Canvas.Left="97" Canvas.Top="12" />  
            
            <Image x:Name="moveImg" Width="50" Height="50" Opacity="0.5" Visibility="Hidden" Panel.ZIndex="11">
                <Image.Effect>
                    <DropShadowEffect/>
                </Image.Effect>
            </Image>
            
            <TextBlock HorizontalAlignment="Center" Height="15.96" Canvas.Left="32" Canvas.Top="96" Width="37">Target:</TextBlock>       
            
            <Button Canvas.Left="75" Canvas.Top="96" MouseEnter="Button_MouseEnter" MouseLeave="Button_MouseLeave" PreviewMouseLeftButtonUp="Button_MouseLeftButtonUp" Panel.ZIndex="12">
                <Grid>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition/>
                        <ColumnDefinition/>
                    </Grid.ColumnDefinitions>
                    <Rectangle Grid.Column="0" Width="100" Height="50" x:Name="rec" Stroke="Black"/>
                    <TextBlock Grid.Column="1" VerticalAlignment="Center" >Click</TextBlock>
                </Grid>
            </Button>
            <Button Grid.Row="2" Click="Button_Click" HorizontalAlignment="Center" Height="22" Canvas.Left="126" Canvas.Top="158" Width="52">Clear</Button>
        </Canvas>
    </Window>

    Code:
    private object resource = null;
    
    private void img_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
    	resource = img.Source;
    	moveImg.Visibility = Visibility.Visible;
    	moveImg.Source = (ImageSource)resource;
    	moveImg.Margin = new Thickness(e.GetPosition(this).X - 25, e.GetPosition(this).Y - 25, moveImg.Margin.Right, moveImg.Margin.Bottom);
    }
    
    private void Button_Click(object sender, RoutedEventArgs e)
    {
    	rec.Fill = null;
    }
    
    private void Window_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
    {
    	resource = null;
    	moveImg.Visibility = Visibility.Hidden;
    }
    
    private void Window_MouseMove(object sender, MouseEventArgs e)
    {
    	if (resource != null)
    		moveImg.Margin = new Thickness(e.GetPosition(this).X-25, e.GetPosition(this).Y-25, moveImg.Margin.Right, moveImg.Margin.Bottom);
    }
    
    private void Button_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
    {
    	if (resource != null)
    	{
    		ImageBrush imgBrush = new ImageBrush((ImageSource)resource);
    		rec.Fill = imgBrush;
    		resource = null;
    		moveImg.Visibility = Visibility.Hidden;
    	}
    }
    
    private void Button_MouseEnter(object sender, MouseEventArgs e)
    {
    	if (resource != null)
    	{
    		moveImg.Visibility = Visibility.Hidden;
    		(sender as Button).Cursor = Cursors.UpArrow;
    	}
    	else
    	{
    		(sender as Button).Cursor = null;
    	}
    }
    
    private void Button_MouseLeave(object sender, MouseEventArgs e)
    {
    	if (resource != null)
    		moveImg.Visibility = Visibility.Visible;
    }
    

     

    Sincerely,

    Bob Bao


    Hope this helps.
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    • Marked as answer by StarterKit Tuesday, March 16, 2010 8:11 PM
    Tuesday, March 16, 2010 6:32 AM

All replies

  • Hi Starterkit,

    Based on my understanding, you want to drag and drop an image from one place to the button by mouse left button. This feature is same with the content of a thread posted by you before: http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/8d858942-fef1-4b6b-9024-a86494d52e6a. Is it right?

    I performed a test based on your description and Jarrey's code. There may be two cases to your issue.

    1. When we click down the mouse left button on the source object and Up it on another object (like Button), the target object could not fire up the MouseLeftButtonUp event. Because of the Button element converts a MouseDown event followed by a MouseUp event into a Click event. It halts the handle (by set the Handled flag). You could do a simple test, add a MouseLeftButtonUp event to a button, and you click this button. The MouseLeftButtonUp event will not be handled.

    One solution, we can use preview event to handle your request in the Button: PreviewMouseLeftButtonUp

    Thanks to Jarrey’s code on that thread, below is my code modified from Jarrey's code:

    <Image x:Name="moveImg" Width="50" Height="50" Opacity="0.5" Visibility="Hidden"  Panel.ZIndex="11">
    ......
    <Button Canvas.Left="75" Canvas.Top="96" PreviewMouseLeftButtonUp="rec_MouseLeftButtonUp" Panel.ZIndex="12">
    	<Grid>
    		<Grid.ColumnDefinitions>
    			<ColumnDefinition/>
    			<ColumnDefinition/>
    		</Grid.ColumnDefinitions>
    		<Rectangle Grid.Column="0" Width="100" Height="50" x:Name="rec" Stroke="Black"/>
    		<TextBlock Grid.Column="1" VerticalAlignment="Center" >Click</TextBlock>
    	</Grid>
    </Button>
    ......


    2. If the Button's ZIndex is less than the MovingImage's, it cannot fire the MouseLeftButtonUp on the Button. Because the pointer dose not contact with the Button directly when we release the left mouse button.

    I suggest that change the drag style like Windows drag style.  We can use a special cursor when we drag an object on the Button. Below is my code based on Jarrey's code:

    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" MouseLeftButtonUp="Window_MouseLeftButtonUp" MouseMove="Window_MouseMove">
        
        <Window.Resources>
            <BitmapImage x:Key="imageRes" UriSource="......"/>
        </Window.Resources>
        <Canvas x:Name="canvas" >
            <TextBlock HorizontalAlignment="Center" Height="15.96" Canvas.Left="52" Canvas.Top="12" Width="39">Source:</TextBlock>
            <Image x:Name="img" Source="{StaticResource imageRes}" Width="50" Height="50" MouseLeftButtonDown="img_MouseLeftButtonDown" Canvas.Left="97" Canvas.Top="12" />  
            
            <Image x:Name="moveImg" Width="50" Height="50" Opacity="0.5" Visibility="Hidden" Panel.ZIndex="11">
                <Image.Effect>
                    <DropShadowEffect/>
                </Image.Effect>
            </Image>
            
            <TextBlock HorizontalAlignment="Center" Height="15.96" Canvas.Left="32" Canvas.Top="96" Width="37">Target:</TextBlock>       
            
            <Button Canvas.Left="75" Canvas.Top="96" MouseEnter="Button_MouseEnter" MouseLeave="Button_MouseLeave" PreviewMouseLeftButtonUp="Button_MouseLeftButtonUp" Panel.ZIndex="12">
                <Grid>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition/>
                        <ColumnDefinition/>
                    </Grid.ColumnDefinitions>
                    <Rectangle Grid.Column="0" Width="100" Height="50" x:Name="rec" Stroke="Black"/>
                    <TextBlock Grid.Column="1" VerticalAlignment="Center" >Click</TextBlock>
                </Grid>
            </Button>
            <Button Grid.Row="2" Click="Button_Click" HorizontalAlignment="Center" Height="22" Canvas.Left="126" Canvas.Top="158" Width="52">Clear</Button>
        </Canvas>
    </Window>

    Code:
    private object resource = null;
    
    private void img_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
    	resource = img.Source;
    	moveImg.Visibility = Visibility.Visible;
    	moveImg.Source = (ImageSource)resource;
    	moveImg.Margin = new Thickness(e.GetPosition(this).X - 25, e.GetPosition(this).Y - 25, moveImg.Margin.Right, moveImg.Margin.Bottom);
    }
    
    private void Button_Click(object sender, RoutedEventArgs e)
    {
    	rec.Fill = null;
    }
    
    private void Window_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
    {
    	resource = null;
    	moveImg.Visibility = Visibility.Hidden;
    }
    
    private void Window_MouseMove(object sender, MouseEventArgs e)
    {
    	if (resource != null)
    		moveImg.Margin = new Thickness(e.GetPosition(this).X-25, e.GetPosition(this).Y-25, moveImg.Margin.Right, moveImg.Margin.Bottom);
    }
    
    private void Button_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
    {
    	if (resource != null)
    	{
    		ImageBrush imgBrush = new ImageBrush((ImageSource)resource);
    		rec.Fill = imgBrush;
    		resource = null;
    		moveImg.Visibility = Visibility.Hidden;
    	}
    }
    
    private void Button_MouseEnter(object sender, MouseEventArgs e)
    {
    	if (resource != null)
    	{
    		moveImg.Visibility = Visibility.Hidden;
    		(sender as Button).Cursor = Cursors.UpArrow;
    	}
    	else
    	{
    		(sender as Button).Cursor = null;
    	}
    }
    
    private void Button_MouseLeave(object sender, MouseEventArgs e)
    {
    	if (resource != null)
    		moveImg.Visibility = Visibility.Visible;
    }
    

     

    Sincerely,

    Bob Bao


    Hope this helps.
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    • Marked as answer by StarterKit Tuesday, March 16, 2010 8:11 PM
    Tuesday, March 16, 2010 6:32 AM
  • Thank You Very Much Bob,

    It worked
    Tuesday, March 16, 2010 8:11 PM
  • Thanks Bob for the tip on Preview versions of the events. That's helped solve one issue. One thing I'm noticing now when capturing using these preview events is that I seem to 'lose' the PreviewMouseUp event. In other words, I click on my button, I capture the PreviewMouseDown event and stop running at the breakpoint set in the handler. When I F5 on through, the PreviewMouseUp event doesn't subsequently fire. I know this event fires though because when I remove the breakpoint from the PMD handler, the PreviewMouseUp breakpoint hits when clicking the button. Do these events time out or bubble on out of existence if nothing catches them pretty much instantly or something weird like that?
    Tuesday, September 21, 2010 1:47 PM
  • Please release the capture after capture the mouse: http://msdn.microsoft.com/en-us/library/system.windows.uielement.releasemousecapture.aspx
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    Are you looking for a typical code sample? Please download all in one code framework !
    Tuesday, September 21, 2010 1:52 PM