How I will get dropping media on mediaelement in wpf? - c#

I am working with mediaelement in wpf, but the problem is I can't drop media on medaiaelement.
can anyone tell me the solution.the following code is .cs file code. I set allow drop property= true
private void mediaElement1_Drop(object sender, System.Windows.DragEventArgs e)
{
String[] FileName = (String[])e.Data.GetData(System.Windows.Forms.DataFormats.FileDrop, true);
if (FileName.Length > 0)
{
String VideoPath = FileName[0].ToString();
mediaElement1.Source = new Uri(VideoPath);
mediaElement1.Play();
}
e.Handled = true;
}

Tried it myself. Actually it will work after you play something there.
Here's the point: assume we have a Grid:
<Grid AllowDrop="True"></Grid>
It won't allow drop.
Now the following
<Grid Background="Transparent" AllowDrop="True"></Grid>
Will allow drop.
The first Grid doesn't have background at all, so actually there's no way to drop anything on it - there's no grid. And in second case there is grid's background even though we can't see it.
The same thing applies to MediaElement. Unfortunately it doesn't have any Background or Content property, so it won't allow drop until you start playing something there.
Solution is to handle drop on MediaElement parent container.
By the way, don't forget to set LoadedBehavior="Manual" for MediaElement so that it will play dropped file.
EDIT.
Here is explanation why MediaElement doesn't allow drop till any content was loaded in it.
Every WPF component is in fact composed of some other basic elements: Borders, Grids, ContentPresenters etc. So something inside the MediaElement handles drop. I cannot tell you what element it is because MediaElement's Template is not accessible. But it really doesn't matter what exactly is the element that handles drag and drop there. What does matter is that there's is nothing material in MediaElement's area until you load content on it - just like in case of my example with Grid at the beginning of this post. I mean that when you move mouse cursor over it's area there is nothing between cursor and MediaElement's container. Try to handle MouseDown event: result will be the same - it won't fire until you load any video. Why? Because there is nothing to raise event. Nothing cannot raise anything.
As I mentioned before there is great difference between Background="{x:Null}" and Background="Transparent": in first case there's no background brush, no background, but in second case there is one. Feel the difference.

Related

WPF HitTest to get ListBoxItem

First things first: I have a WPF project which uses C# and MVVM (MVVM Light), in Visual Studio 2010.
I have a Canvas control inside which is a ListBox - each ListBoxItem can be moved around with mouse drag (each has a DataTemplate contains a Thumb control to allow each item to be dragged).
That looks as follows:
<DataTemplate>
<Grid Background="Transparent">
<Thumb Name="myThumb" Template="{StaticResource NodeVisualTemplateRegular}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="DragDelta">
<cmd:EventToCommand Command="{Binding ChatNodeListViewModel.DragDeltaCommand, Source={StaticResource Locator}}" PassEventArgsToCommand="True"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</Thumb>
</Grid> </DataTemplate>
As you can see, there's a command which handles the dragging part (DeltaDragCommand).
None of this is a problem, but then I wanted to add the ability to pan around the Canvas control with a click and drag motion. This is where things come into conflict with the above stated dragging of ListBoxItems.
The Canvas pan stuff is handled in the code behind and the subscriptions for the events look like this:
NodeDragScrollViewer.PreviewMouseLeftButtonDown += OnMouseLeftButtonDown;
NodeDragScrollViewer.PreviewMouseLeftButtonUp += OnMouseLeftButtonUp;
NodeDragScrollViewer.MouseMove += OnMouseMove;
NodeDragScrollViewer.PreviewMouseWheel += OnPreviewMouseWheel;
NodeDragScrollViewer.ScrollChanged += OnScrollViewerScrollChanged;
The events we see here are run on the ScrollViewer (a control in which the Canvas control sits). The problem is that these events sit 'on top of' the ListBoxItems - the click for the pan of the canvas will activate before the click for the drag of the ListBoxItem.
Now a solution I've seen is to use the VisualTreeHelper HitTest method to find out what was clicked on. If I can find out if a ListBoxItem was clicked on, then I can ignore the Canvas pan actions and let things progress as before.
The problem I'm facing is that I just can't get this to work. I have seem people explain how this should work and have borrowed code for this action. I present that code here:
Point pt = new Point();
VisualTreeHelper.HitTest(NodeDragCanvas, null,
new HitTestResultCallback(MyHitTestResult),
new PointHitTestParameters(pt));
private HitTestResultBehavior MyHitTestResult(HitTestResult result)
{
var p = FindParent<ListBoxItem>(result.VisualHit);
//Set the behavior to return visuals at all z-order levels.
return HitTestResultBehavior.Continue;
}
public static T FindParent<T>(DependencyObject child) where T : DependencyObject
{
//get parent item
DependencyObject parentObject = VisualTreeHelper.GetParent(child);
//we've reached the end of the tree
if (parentObject == null) return null;
//check if the parent matches the type we're looking for
T parent = parentObject as T;
if (parent != null)
return parent;
else
return FindParent<T>(parentObject);
}
If you look at the contents of HitTestResultBehaviour, this is where I check for the control that I've clicked on. I'm hoping it will be a ListBoxItem... but that always returns 'null'. I am aware that the method can fire multiple times, but I've never seen the var p (in this case) be anything other than a null value. If, however, I attempt to use FindParent<ListBox>, I will get returned the ListBox. It has the right amount of items in it and seems to be as I would expect. But this doesn't work for me since my ListBox is the size of the Canvas.
It seems this is the key point, but I don't know what else to try and all avenues of research seem to lead back to this method.
Can anyone offer any guidance?
Thanks
Yes, obviously you need to use the PreviewXXX events on the Canvas, or you wouldn't get the mouse events for the ListBoxItems in the Canvas because the ListBoxItem already ate them.
You might want to consider restructuring your code so that instead of using a ListBox, you use a MyListBox (or whatever you want to call it) and trap the ListBoxItem mouse events there and handle just the Canvas dragging in the Canvas. The way you have it now, you are intermingling both of those cases when they are really completely separate. The canvas should handle its thing and the list box should handle its thing.
If you want to keep the code how you have it now, take a look at the MouseEventArgs, original source, sender, etc. One of those might have the original sender, but it'll probably be a TextBlock rather then a ListBoxItem since that's the top level item, so...
Google around for a well known class VisualTreeExtensions and use that. When you get the TextBlock or whatever, you can just do something like ((DependencyObject)e.OriginalSource).GetVisualAncestor<ListBoxItem>() and if it's not null, you know you're inside of a ListBox.

WPF application in one window

I am new in WPF and want to create WPF application like cookbook. I already done this and app work correctly. But I make it in this way:
First screen show buttons, which open new windows to do something. As a result i have 14 different windows. It is ok, but now i want to make it in other way.
I am trying to make one window, which will be showed at start, and change content. I divided window on two grids. First is static and is placed on bottom. It contains buttons, which represents functionality of the program. Second one will be dynamic. There i want to show content of every window. So i want to change content of this panel instead of creating new windows.
I tried to make *.cs files which will create controls in code-behind, functions and data. But my idea is not succesful and i do not know how to do this.
At all, I want to create app, which will work like this:
- if you click button "Add receip" then app will show controls to add name, ingredients and save it at the end.
- if you clik "Show receip" previous content will be replaced by list of ingredients
and etc.
I hope you will understand me.
You can create a Frame instead of second grid. Frame allows you to show pages, and not in seperate windows, in Frame itself. You can navigate the frame into the page like
mainFrame.Source = new Uri("Page1.xaml",UriKind.Relative);
This changes the frame to your page. You can change the source again, if you wanna change the page again.
Note: You can add tags to your buttons like "showReceip" and you can make just one buttonclick event for your buttons. Code will look like this.
mainFrame.Source = new Uri((sender as Button).Tag.ToString() + ".xaml",UriKind.Relative);
That takes the tag of your clicked button, add the string ".xaml" on it and take it on the source part. So, if your tag is "Page1", Source will look like "Page1.xaml" as my solution.
Appreciate the try, I hope you are looking for WPF user controls instead for separate windows. User controls are similar to windows you can create the UI and functionalities in the user control. I would like to recommend you to design the main window like the following:
<Grid>
<Canvas Name="canFunctionalButtons">
<!--Define the buttons inside this canvas
And allocate proper place for this in the UI
-->
</Canvas>
<Canvas Name="canControlContainer">
<!--This is to display the user control
Which can be changed dynamically according to the Button's click
-->
</Canvas>
</Grid>
Then you have to add click event for those buttons, which will add specific user control to the canControlContainer canvas. An example for adding an user control to this canvas is as follows, Let btnAddSomething be a button and btnAddSomething_Click be its click event then you can do something like:
private void btnAddSomething_Click(object sender, RoutedEventArgs e)
{
canControlContainer.Children.Clear(); // will remove previous contols from this canvas
// UC_AddSomething be the user control that you wanted to add here
canControlContainer.Children.Add(new UC_AddSomething());
}

Windows Phone 8.1 ManipulationDelta Event

I'm really confused about this Topic. None of the tutorials I found to e.g. move objects around when there's touch input works. For example they all do something like this:
Control.AddHandler(UIElement.ManipulationStartedEvent, new EventHandler
<ManipulationStartedEventArgs>(Control_ManipulationStarted), true);
But there's no ManipulationStartedEventArgs, VS2013 can't find it and there's no way to add a using directive. Are those tutorials old and did MS change the way the ManipulationDelta works?
Adding it with the EventHandler section of the Properties section again doesn't work, no Event is fired no matter what I'm trying to do.
For manipulation to work the UI Element must have ManipulationMode property set to something other than None or System to be a manipulation event source; i.e Set ManipulationMode to TranslateX if you want an event to fire on a horizontal pointer movement.
For UI manipulation in Windows Universal you have 3 events:
ManipulationStarted
ManipulationDelta
ManipulationCompleted
Each with their own EventArgs under System.Windows.Input namespace
ManipulationStartedEventArgs
ManipulationDeltaEventArgs
ManipulationCompletedEventArgs
The problem may however be the type of UI Element that you are using, not all accept/generate manipulation events.
Examples of UI Elements that don't:
WebView
(I expect Canvas but not sure, haven't tested)
Examples of UI Elements that do:
Textblock
ListView

LongListSelector interaction breaks when a popup is open in WP8

To dynamically place some content on a page in a Windows Phone 8 project, we use a popup with a grid to host the content.
When this page contains a LongListSelector control, the Tap interaction to stop scrolling no longer works. Swiping up and down works as expected.
The issue can be reproduced very easily by starting with a new Databound app and adding this piece of code in the page constructor:
private Popup p;
p = new Popup();
Grid grid = new Grid();
grid.Width = Application.Current.Host.Content.ActualWidth;
grid.Height = Application.Current.Host.Content.ActualHeight;
p.Child = grid;
p.IsOpen = true;
Using this code you can make the LongListSelector scrolling but a Tap does no longer work to stop the scrolling.
Has anyone seen this issue and found a solution or might this be a known issue with the LongListSelector?
The invisible Grid that you're putting over the LongListSelector (actually the whole page) is capturing the tap event and because the popup is not part of the visual tree the event doesn't bubble as you're expecting.
The anomaly here is that you can actually interact with the LLS at all.
The real question here isn't why this happens but why you'd do this? Obviously your reproduction is very simple but it's to a point that makes no sense.
What are you ultimately trying to achieve?
There are almost certainly more appropriate alternative ways to achieve your end goal.

AutoCompleteComboBox Arrow Up/Arrow Down keys to scroll list

I created a simple AutoCompleteBox in my WPF app and it loads great with code intercepting the Populate event, but when the list pops up and I hit the arrow down key and get to the end of the list the vertical scroll bar doesn't scroll.
The values keep changing in the field like it is scrolling through them, but the scroll bar doesn't move.
If I use the mouse it scrolls fine.
I just need the arrow key to scroll it.
Any ideas/suggestions?
I am new to WPF and have searched forever for this fix.
Attach a SelectionChanged event and then, inside the handler:
private void AutoCompleteBox_OnSelectionChanged(object sender, SelectionChangedEventArgs e)
{
AutoCompleteBox box = (AutoCompleteBox)sender;
ListBox innerListBox = (ListBox) box.Template.FindName("Selector", box);
innerListBox.ScrollIntoView(innerListBox.SelectedItem);
}
I see the same behavior. I found a post on codeplex talking about a different issue but at the bottom of the post they have a class AutoCompleteBoxEx that supports ScrollIntoView, so you can hook up the SelectionChanged even and this should get you the behavior you want. I have no idea why this is not baked in. I have had a chance to test out the posted code.
Update
Just pasted the code from the post into a class and used it in the XAML by changing AutoCompleteBox to AutoCompleteBoxEx and adding namespace for AutoCompleteBoxEx and it worked fine. You don't have to specify any event in the XAML, nor do you need to add any code to the code behind.

Categories