Drag&Drop Failure with Scatterview Items and Grid Layout - c#

Link to the Image of my App
I want to detect if the 2 Pictures on canvas are neary each other, an than make some compare operation with the data that is embedded in the pictures if both are touched an near each other.
The brown Area is a ScatterView where i can drop picture elements an add them to the green listbox.
I can drop picture items directly from the blue list box to the brown drop area.
But when i drop them first on the yellow scatterview, then i can't get out of there to drop them on the brown scatterview.
<Grid ShowGridLines="True">
<Grid.RowDefinitions >
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
</Grid.ColumnDefinitions>
<s:ScatterView
Grid.Row="0"
Grid.Column="0"
Grid.ColumnSpan="2"
Grid.RowSpan="1"
x:Name="ScatterLayer"
Background="Yellow"
ItemContainerStyle="{StaticResource ScatterItemStyle}"
AllowDrop="True"
ItemTemplate="{StaticResource ImageAndCaptionTemplate}"
ItemsSource="{Binding ScatterItems}"
s:SurfaceDragDrop.Drop="ScatterLayer_Drop"
s:SurfaceDragDrop.DragEnter="ScatterLayer_DragEnter"
s:SurfaceDragDrop.DragCompleted="ScatterLayer_DragCompleted" >
</s:ScatterView>
<s:SurfaceListBox
Grid.Row="0" Grid.Column="2"
AllowDrop="True"
x:Name="ListBoxVerticalBasket"
VerticalAlignment="Top"
Background="GreenYellow"
ItemsSource="{Binding Path=BasketItems}"
ItemTemplate="{StaticResource BasketTemplate}" >
<s:SurfaceListBox.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Vertical" />
</ItemsPanelTemplate>
</s:SurfaceListBox.ItemsPanel>
</s:SurfaceListBox>
<s:SurfaceListBox
Grid.Row="1"
Grid.Column="0"
Grid.ColumnSpan="2"
x:Name="ShoppingList"
AllowDrop="True"
s:SurfaceDragDrop.DragCompleted="OnShoppingListDragCompleted"
s:SurfaceDragDrop.DragCanceled="OnShoppingListDragCanceled"
PreviewMouseLeftButtonDown="OnShoppingListPreviewMouseLeftButtonDown"
PreviewMouseMove="OnShoppingListPreviewMouseMove"
PreviewMouseLeftButtonUp="OnShoppingListPreviewMouseLeftButtonUp"
ItemsSource="{Binding Path=LibraryItems}"
ItemTemplate="{StaticResource ImageAndCaptionTemplate}"
PreviewTouchDown="OnShoppingListPreviewTouchDown"
PreviewTouchMove="OnShoppingListPreviewTouchMove"
PreviewTouchUp="OnShoppingListPreviewTouchUp"
Background="#FF00BDD8">
<s:SurfaceListBox.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" AllowDrop="True"/>
</ItemsPanelTemplate>
</s:SurfaceListBox.ItemsPanel>
</s:SurfaceListBox>
<s:ScatterView
Grid.Column="2"
Grid.Row="1"
Background="DarkGoldenrod"
Width="300"
Height="100"
x:Name="ScatterViewDropArea"
VerticalAlignment="Top"
HorizontalAlignment="Left"
AllowDrop="True"
s:SurfaceDragDrop.Drop="ScatterViewDropArea_Drop">
</s:ScatterView>

I think you should consider using the DragDropScatterView that comes with the Shopping Cart demo in the Surface SDK instead of ScatterView.

Related

WPF Listbox stretching issues

I have created a UserControl that is suppose to display some text and then present a listbox for the user to select some item.
It is supposed to strech to the height to the grid cell it is placed in. And if there are more items than can fit on screen then to display a vertical scrollbar. After much trial and error I have finally managed to get it working as expected. But only when the row height is a pixel value. If I use any partial (by partial I mean the star symbol), the grid cell's height is not contained. Since I need the app the match screen size I need the partials to work.
Putting 100 items in the listbox suddenly makes the height of the entire grid is around 11000 (which I think is everything with no contraint). Meaning there is no scrollbar. See [Screenshot] https://i.stack.imgur.com/faES9.png.
I have a similar issue with my TextBox only horizontally. It will only activate when clicking on a specific pixel since it is empty the width is only 1 pixel. I hope someone can help me point out where I am going wrong, cause since I'm having more than one issue I suspect the problem is on my end.
This is my XAML code.
<UserControl x:Class="PackingStation.UserControls.SearchItemListing"
x:Name="SearchItemListingRoot"
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:local="clr-namespace:PackingStation.UserControls"
mc:Ignorable="d"
d:DesignHeight="1000" d:DesignWidth="1000">
<Grid DataContext="{Binding ElementName=SearchItemListingRoot}"
x:Name="TheGrid"
VerticalAlignment="Stretch">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="1*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height=".1*" />
<RowDefinition Height=".1*" />
<!-- If this value isnt a pixel value it will not vertically strech to available space -->
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<StackPanel HorizontalAlignment="Center"
Margin="0,0,0,0"
x:Name="TheHeadLineField"
Grid.Row="0"
Grid.Column="1">
<Label Style="{StaticResource LabelStyleHeadline32}"
Content="{Binding Title}"
HorizontalAlignment="Left"/>
<Label Style="{StaticResource LabelStyleText}"
HorizontalAlignment="Left"
Content="{Binding SubTitle}"
FontSize="20"/>
</StackPanel>
<!-- Search Field -->
<Border Style="{StaticResource Border6}"
x:Name="TheSearchField"
Grid.Row="1"
Grid.Column="1"
Background="{StaticResource ColorSummaryPanelBackground}"
BorderBrush="{StaticResource ColorSummaryPanelBorder}"
BorderThickness="1"
Margin="0,40,0,0">
<StackPanel Orientation="Horizontal"
Height="78"
HorizontalAlignment="Stretch">
<Image Stretch="Uniform"
Height="24"
Source="pack://application:,,,/WpfUI;component/Icons/Search.png"
Margin="36,0,0,0"
VerticalAlignment="Center"/>
<!-- Search Textbox -->
<!-- Similar issue with this textbox, only horizontally. With no content you have to hit a specific pixel to activate it -->
<TextBox Style="{StaticResource TextBoxSearchInlay}"
Name="TbxSearchTerm"
TextChanged="TextBoxBase_OnTextChanged"
HorizontalContentAlignment="Stretch"
HorizontalAlignment="Stretch"
Margin="20,0,0,0"/>
</StackPanel>
</Border>
<!-- Search results listings -->
<ListBox ItemsSource="{Binding Items}"
x:Name="TheListBox"
Grid.Row="2"
Grid.Column="1"
SelectedItem="{Binding SelectedItem, Mode=TwoWay}"
ScrollViewer.VerticalScrollBarVisibility="Auto"
HorizontalContentAlignment="Stretch"
VerticalContentAlignment="Stretch">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel HorizontalAlignment="Stretch" Margin="0,-10,0,-10">
<Label Style="{StaticResource LabelSearchItem}"
Content="{Binding Name}"
HorizontalContentAlignment="Stretch"
HorizontalAlignment="Stretch"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
</UserControl>
I could repro your problem when I put your UserControl in a StackPanel. When it's in a Grid the ListBox shows its vertical scrollbar. So, try your UserControl in a Grid.
I think this answer will give a good explanation about Grid and StackPanel stretching behavior.

Expand grid cells but stop at contents of listBox

I have a WPF form with some text fields and two ListBoxes:
<TextBlock>Label</TextBlock>
<TextBox Text="{Binding Input}"/>
<TextBlock>List Label</TextBlock>
<ListBox ItemsSource="{Binding Items1}"/>
<TextBlock>Second List Label</TextBlock>
<ListBox ItemsSource="{Binding Items2}"/>
I'd like for the two ListBoxes to expand vertically to fit their container, but for each one to stop expanding once its scrollbar is no longer necessary. The closest I've come is with a grid:
<Grid VerticalAlignment="Top">
<Grid.RowDefinitions>
<RowDefinition Height="auto" />
<RowDefinition Height="*" MinHeight="40" />
<RowDefinition Height="auto" />
<RowDefinition Height="*" MinHeight="40" />
</Grid.RowDefinitions>
<StackPanel Grid.Row="0">
<TextBlock>Label</TextBlock>
<TextBox Text="{Binding Input}"/>
<TextBlock>List Label</TextBlock>
</StackPanel>
<ListBox Grid.Row="1" ItemsSource="{Binding Items1}"/>
<TextBlock Grid.Row="2">Second List Label</TextBlock>
<ListBox Grid.Row="3" ItemsSource="{Binding Items2}"/>
</Grid>
However, then the space taken up by the list boxes is always the same due to the asterisk row height, so if one list stops growing, the remainder of the height to match the other list is left as empty space at the bottom of the grid.
What you want is a DockPanel...
<DockPanel >
<TextBlock DockPanel.Dock="Top">Label</TextBlock>
<TextBox Text="{Binding Input}" DockPanel.Dock="Top"/>
<TextBlock DockPanel.Dock="Top">List Label</TextBlock>
<ListBox Grid.Row="1" ItemsSource="{Binding Items1}" DockPanel.Dock="Top" MinHeight="40" MaxHeight="200"/>
<TextBlock Grid.Row="2" DockPanel.Dock="Top">Second List Label</TextBlock>
<ListBox Grid.Row="1" ItemsSource="{Binding Items2}" MinHeight="40"/>
</DockPanel>
This fulfills all of your requirement. The container is completely filled. The listboxes stop expanding when scrollbars are no longer needed. However if there are too many items in the 1st listbox the 2nd one will disappear completely. This is why I put in a max height for the first list box.

UWP XAML Button with image and text in a Hub [duplicate]

This question already has an answer here:
How do I place a text over a image in a button in WinRT
(1 answer)
Closed 5 years ago.
I am learning different ways of achieving certain layouts with XAML in UWP (I know I'm late to the party but I just started with the UWP stuff!)
What I am trying to achieve is a main navigation page kind of thing from a hub control on my main page. At every HubSection, I will have button on each column of a 2-column grid, which will contain buttons. Ive'tried something similar to this post but the debugger kept failing to attach to my UWP app when I used images instead of textblocks.
Essentially, what I've got until now is something like this: (I've shared my code down below)
But what I am trying to achieve is each button having its own image background and a separate TextBlock with semi-transparent background at the bottom centre of the button... (I've only photo shopped it, this is the thing I am trying to achieve...)
So this is what I've tried so far... I've also tried the relative panel but no luck...
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="200" />
<ColumnDefinition Width="200" />
</Grid.ColumnDefinitions>
<StackPanel Orientation="Vertical" Grid.Column="0" Margin="10,10,10,0">
<Button HorizontalAlignment="Stretch">
<Grid>
<TextBlock HorizontalAlignment="Center">Column 0 Item 1</TextBlock>
<Image Source="/Assets/Artwork/150x150/RobCos_Worst_Nightmare_trophy.jpg" Stretch="None" />
</Grid>
<StackPanel>
<TextBlock>Column 0 Item 1</TextBlock>
<Image Source="/Assets/Artwork/150x150/RobCos_Worst_Nightmare_trophy.jpg" Stretch="None" />
</StackPanel>
</Grid>
My complete code looks something like this for this page.
<Page
x:Class="VaultManager.Terminal.Views.MainPage"
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">
<Grid Background="Black">
<Hub SectionHeaderClick="Hub_SectionHeaderClick">
<Hub.Header>
<Grid Margin="0,20,0,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="80"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock x:Name="pageTitle" Text="My Hub Sample" Style="{StaticResource SubheaderTextBlockStyle}" Grid.Column="1" IsHitTestVisible="false" TextWrapping="NoWrap" VerticalAlignment="Top"/>
</Grid>
</Hub.Header>
<HubSection Header="Overview">
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="200" />
<ColumnDefinition Width="200" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="150" />
</Grid.RowDefinitions>
<StackPanel Orientation="Vertical" Grid.Column="0" Margin="10,10,10,0">
<Button HorizontalAlignment="Stretch">
<StackPanel>
<TextBlock>Column 0 Item 1</TextBlock>
<Image Source="/Assets/Artwork/150x150/RobCos_Worst_Nightmare_trophy.jpg" Stretch="None" />
</StackPanel>
</Button>
<Button HorizontalAlignment="Stretch" >
<RelativePanel>
<TextBlock>Column 0 Item 2</TextBlock>
<Image Source="/Assets/Artwork/150x150/RobCos_Worst_Nightmare_trophy.jpg" Stretch="None" />
</RelativePanel>
</Button>
</StackPanel>
<StackPanel Orientation="Vertical" Grid.Column="1" Margin="10,10,10,10">
<Button HorizontalAlignment="Stretch">
<StackPanel>
<TextBlock>Column 1 Item 1</TextBlock>
<Image Source="/Assets/Artwork/150x150/RobCos_Worst_Nightmare_trophy.jpg" Stretch="None" />
</StackPanel>
</Button>
<Button HorizontalAlignment="Stretch" >
<StackPanel>
<TextBlock>Column 1 Item 2</TextBlock>
<Image Source="/Assets/Artwork/150x150/RobCos_Worst_Nightmare_trophy.jpg" Stretch="None" />
</StackPanel>
</Button>
</StackPanel>
</Grid>
</DataTemplate>
</HubSection>
<HubSection Header="Videos" Name="Videos">
<!-- yada yada -->
</HubSection>
<HubSection Header="Audios" Name="Audios">
<!-- blah blah -->
</HubSection>
</Hub>
</Grid>
Good job giving us all that info. You may want to take a look here since the asker in that question seems to have had a similar issue. The answerer suggested using a Grid instead of a StackPanel. Hope that helps. After that, you should be able to adjust the transparency of the text. If you are using visual studio you can just click on the text element and adjust the background brush from the Properties tab. The button w/ the image should look like this:
<Button HorizontalAlignment="Stretch">
<Grid>
<TextBlock Text = "Column 0 Item 1">
<TextBlock.Background>
<SolidColorBrush Color="(**Colour here**)" Opacity = "(**Opacity Here {1 being opaque and 0 being transparent}**)/>
</TextBlock.Background></TextBlock>
<Image Source="/Assets/Artwork/150x150/RobCos_Worst_Nightmare_trophy.jpg" Stretch="None" />
</Grid>
</Button>

ContentControl MouseDoubleClick event does not work when the content changes

I have a DataTemplate like this:
<!-- MULTI VIEW TEMPLATE -->
<DataTemplate x:Key="MultiViewTemplate" >
<Grid x:Name="MultiViewGrid" ShowGridLines="True" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<ContentControl Content="{StaticResource BorderHwnd1}" Grid.Column="0" Grid.Row="0" x:Name="MultiViewBorder1" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" MouseDoubleClick="MultiViewBorder1_MouseDoubleClick"/>
<ContentControl Content="{StaticResource BorderHwnd2}" Grid.Column="1" Grid.Row="0" x:Name="MultiViewBorder2" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" MouseDoubleClick="MultiViewBorder2_MouseDoubleClick"/>
<ContentControl Content="{StaticResource BorderHwnd3}" Grid.Column="0" Grid.Row="1" x:Name="MultiViewBorder3" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" MouseDoubleClick="MultiViewBorder3_MouseDoubleClick"/>
<ContentControl Content="{StaticResource BorderHwnd4}" Grid.Column="1" Grid.Row="1" x:Name="MultiViewBorder4" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" MouseDoubleClick="MultiViewBorder4_MouseDoubleClick"/>
</Grid>
</DataTemplate>
And the BorderHwnd1 is like this:
<Border x:Key="BorderHwnd1" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" BorderBrush="Transparent" BorderThickness="0" Background="Transparent" >
<Image Margin="1" Source="/MyProject;component/Images/No_image_available.png" />
</Border>
My problem is that MultiViewBorder1_MouseDoubleClick event does not work after I remove and assign programmatically a new child to MultiViewBorder1. Initially MultiViewBorder1.Child is an image (No_image_available.png). In my code, I remove the image and assign a new child. This new child is a HwndHost.
Where is my mistake? any help is appreciated!
The child is changing from a WPF Image control....which is able to raise/flow "routed" "mouse" events through the visual tree....to some "hwnd" which you have inside the HwndHost, which is handling raw WIN32 mouses messages....and doesn't route them.
To be able to get mouse activity in your HwndHost into the visual tree, you could use a few different techniques to get them routed.
have an overlayed "transparent" window
handle the "mouse" messages in your WIN32/Hwnd, and then use "delegates" to raise
How can I convert Win32 mouse messages to WPF mouse events?
WPF WIN32 hwndhost WM_MOUSEMOVE WM_MOUSEHOVER

How to make controls fill the container in WPF?

Below is my xaml code :
<Window x:Class="ScoresBank.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow">
<DockPanel LastChildFill="True">
<WrapPanel DockPanel.Dock="Top">
<ToolBar Height="25"></ToolBar>
</WrapPanel>
<WrapPanel DockPanel.Dock="Bottom">
<StatusBar Name="stbBottom" Height="25"
BorderThickness="2"
BorderBrush="Black">Example</StatusBar>
</WrapPanel>
<StackPanel DockPanel.Dock="Left">
<DockPanel LastChildFill="True">
<WrapPanel DockPanel.Dock="Top">
<Button Name="btnBrowseTags">TAGS</Button>
<Button Name="btnBrowseTitles">TITLES</Button>
</WrapPanel>
<ComboBox DockPanel.Dock="Top" Name="cbxCategory">
Example
</ComboBox>
<WrapPanel DockPanel.Dock="Bottom">
<TextBox Name="txtKeyword"></TextBox>
<Button Name="btnFind">Find</Button>
</WrapPanel>
<ListBox Name="lbxBrowse">
</ListBox>
</DockPanel>
</StackPanel>
<StackPanel DockPanel.Dock="Right">
<Button>Example</Button>
</StackPanel>
<Canvas>
</Canvas>
</DockPanel>
And this is my current layout view :
So, what I mean with filling the container are :
Making lbxBrowse to fill the mid-space of the DockPanel inside the left StackPanel.
Making txtKeyword to fill the WrapPanel.
Making stbBottom to fill the WrapPanel.
What I've tried :
It seems i've put them in a DockPanel with LastChildFill="True". But it seems doesn't work.
I don't know about this, since it's not possible to put it into a DockPanel first.
I don't know anything about this.
I don't use fixed size, since I need them to keep neat even when resized in multiple screen resolution. The fixed size on ToolBar and StatusBar seems required, otherwise, the text will be unseen.
P.S. If possible, I prefer the solution to be XAML code, rather than the C# code. Otherwise, C# code is fine too.
Thank you.
You should use a Grid. It is more easier to configure. Here is an example (I don't know exactly how you want to setup your layout).
<Window x:Class="SampleWpf.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="400" Width="600">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Button Margin="5" Content="TAGS"
Grid.Column="0" Grid.Row="0" />
<Button Margin="5" Content="TITLES"
Grid.Column="1" Grid.Row="0" />
<Button Margin="5" Content="EXAMPLES"
Grid.Column="2" Grid.Row="0"
HorizontalAlignment="Right"/>
<ComboBox Margin="5"
Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="1" />
<ListBox Margin="5"
Grid.Column="2" Grid.Row="1" Grid.RowSpan="2" />
<Button Margin="5" Content="EXAMPLE"
Grid.Column="2" Grid.Row="3" HorizontalAlignment="Left" />
</Grid>
</Window>
And the result:
With a grid you can set the height and the width of the columns and rows to a specific value (in points, pixels, cm, etc.), to column content (Auto) or proportional to the grid (with *).
Instead of using a StackPanel and DockPanel you can use Grid and set Grid.ColumnDefinitions and Grid.RowDefinitions. You can specify directly each row Height and each column Width. It's easier to use and it automaticly fit to content and container.

Categories