ContextMenu.SourceControl property doesn't exists - c#

I am making a WPF .NET 4.8 Exe application.I placed an TreeView control and made a void that is firing when window is loaded.This void adds all the sub directories and all of the files in all the sub directories and adds them to TreeView as TreeViewItem, and when they are creating their ContextMenu property is binding to a premade ContextMenu control.It also binds a click event to the MenuItems that ones ContextMenu contains.
I scripted the click event's void as RoutedEventArgs and wrote the code below (tried to access the TreeViewItem i created before).
I made some changes in my code to fix that problem but it did not work.
The code before:
void showInExplorerFolder_Click(object sender, RoutedEventArgs e)
{
Console.WriteLine("event triggered");
MenuItem menuItem = (MenuItem)sender;
//string tag = menuItem.Tag.ToString();
ContextMenu parent = (ContextMenu)menuItem.Parent;
var baseParent = parent.SourceControl;
Console.WriteLine("got success parent; ; ; ; ; ;" + menuItem.Name);
}
The code after:
void showInExplorerFolder_Click(object sender, RoutedEventArgs e)
{
Console.WriteLine("event triggered");
MenuItem menuItem = (MenuItem)sender;
//string tag = menuItem.Tag.ToString();
ContextMenu parent = (ContextMenu)menuItem.Parent;
TreeViewItem baseParent = (TreeViewItem)parent.SourceControl;
Console.WriteLine("got success parent; ; ; ; ; ;" + menuItem.Name);
}
And after theese changes i could not find any solution.
And the error code is here:
CS1061 'ContextMenu' does not contain a definition of 'SourceControl' and no inaccessible extension method 'SourceControl' is available that accepts a first argument of type 'ContextMenu' (maybe you are missing a usage or annotation reference?)
I could not find any solution.If anyone could help me, i will be thankful.

What you have done here is mixed WinForms code sample with WPF application.
To solve your problem you need to change
(TreeViewItem)parent.SourceControl; which is WinForms as SourceControl is part of ControlMenuStrip which lives in System.Windows.Forms.dll MSDN link, this is very important as WPF doesn't use that dll. It is a separate technology which uses different operating system components to render UI. For example WinForms is using GDI+ where WPF uses DirectX to render onto screen. Because of that you can't mix the 2 together as they are fundamentally different.
Solution
Use this ((sender as MenuItem).Parent as ContextMenu).PlacementTarget as it is using WPF Controls and it is the equivalent of SourceControl. Here is a link to MSDN that will show you, it is in a different assembly.
Hope this helps

Related

Can't access ItemInvoked event handler of WindowsXamlHost control

I use xamlIslands to host a custom UWP control in a WPF, .NetCore3 project. I followed instructions from this MSDN article in order to use UWP controls in WPF - Host a custom UWP control in a WPF app using XAML Islands
Other articles mention that the WindowsXamlHost's ChildChanged event handler is used to access the underlying UWP control's properties, handle events etc. Therefore, I am trying to access the ItemInvoked handler within the WPF project's window.xaml.cs file
I tried the linked article above's code. ItemInvoked it not listed by the dropdown as a choosable event for userControl below:
private void WindowsXamlHost_ChildChanged(object sender, EventArgs e)
{
WindowsXamlHost windowsXamlHost = sender as WindowsXamlHost;
global::MyUWPApp.CustomControls.myNavigationView userControl =
windowsXamlHost.GetUwpInternalObject() as global::MyUWPApp.CustomControls.myNavigationView;
}
Another Approach which does give ItemInvoked as optional event handler:
private void WindowsXamlHost_ChildChanged(object sender, EventArgs e)
{
var host = (WindowsXamlHost)sender;
var myNavView = host.Child as Windows.UI.Xaml.Controls.NavigationView;
myNavView.ItemInvoked += MyNavView_ItemInvoked; ;
}
private void MyNavView_ItemInvoked(NavigationView sender, NavigationViewItemInvokedEventArgs args)
{
throw new NotImplementedException();
}
Building that breaks on myNavView.ItemInvoked += MyNavView_ItemInvoked; with error System.ArgumentException: 'Delegate to an instance method cannot have null 'this'.
Hovering with mouse on myNavView within the code above gives info: (local variable) NavigationView myNavView
I guess that does not work because it is not an instance of the object.
General info:
The custom control is "hosted" in a UWP project, which is linked to the WPF project. As according to the article mentioned above. Within the WPF project window where I want to use the custom control, the following event handlers are accessible which seem relevant or possibly useful, in window.xaml:
<xaml:WindowsXamlHost InitialTypeName="MyUWPApp.CustomControls.myNavigationView"
ChildChanged="WindowsXamlHost_ChildChanged"
Loaded="WindowsXamlHost_Loaded_1"
Initialized="WindowsXamlHost_Initialized"
/>
I want to be able to access ItemInvoked event handler to properly manage selections in a UWP NavigationView, as according to this MSDN article: Using the NavigationView in your UWP applications

Clone ScatterViewItem control in Surface Application

I'm working on a Windows multitouch application using Surface 2.0 SDK.
I need to "clone" a control, in this specific case a ScatterViewItem, in which I've added a ElementMenu with a "CopyButton" with a Click event handler.
This is my ScatterViewItem:
<s:ScatterViewItem x:Name="PhotoPadSVI" MinWidth="296" Background="Transparent" Style="{StaticResource ScatterViewItemStyle}">......</ScatterViewItem>
And this is the code that I used and that doesn't work:
void DocumentDuplicate_Click(object sender, RoutedEventArgs e)
{
ScatterViewItem swi = PhotoPadSVI; //error is already here cause I set it as the same, but I cannot found a ".Clone()" like method
swi.Visibility = System.Windows.Visibility.Visible;
swi.ZIndex = 100;
swi.VerticalAlignment = System.Windows.VerticalAlignment.Bottom;
//sView.Items.Add(swi); cannot add to ScatterView cause swi is equal to PhotoPadSVI
}
Question: Do you know in which way could I replicate the ScatterViewItem?
You need to construct a new instance of ScatterViewItem. It should work if you set its Content the same as PhotoPadSVI's.
ScatterViewItem swi = new ScatterViewItem() { Content = PhotoPadSVI.Content };
If there is still error indicating you can't add the same item to ScatterView, you have to do from scratch, create the new ScatterViewItem's Content from code, this can be a lot more complicated if PhotoPadSVI's Content is a bunch of XAML code.
Also refer to this blog.

Sharing objects between classes

I have a program written in c# that contains a listbox with an observable collection. I want a balloon to pop-up for the user (in the system tray) when the collection has an item added. I have a class that contains a method for notifying the listbox when an item is added (see below):
void OnFileCreated(object sender, FileSystemEventArgs e)
{
if (!base.Dispatcher.CheckAccess())
{
base.Dispatcher.BeginInvoke(
DispatcherPriority.Normal,
(FileSystemEventHandler)OnFileCreated,
sender, e);
}
else
{
// Ignore new directories.
if (File.Exists(e.FullPath))
{
Debug.WriteLine("File Created: " + e.FullPath);
_files.Add(new ObservableFileInfo(e.FullPath));
//Alert users to new request
string title = "Access Request";
string text = "A new access request has been submitted";
//show balloon with built-in icon
tbi.ShowBalloonTip(title, text, BalloonIcon.Error);
}
}
}
The code works exactly as intended apart from the fact that the balloon will only show if I create a new instance of the balloon within the OnFileCreated method (not seen above as I took the code out). For reference, I am using the system tray icon .dll from the following project: http://www.codeproject.com/Articles/36468/WPF-NotifyIcon?fid=1540774&select=4624878&fr=51#xx0xx
My issue is that I already have a system tray icon initiated in the MainWindow class, but I cannot call on it to show a balloon from my OnFileCreated method. I am not sure how I can "share" this information across classes.
If anyone has any ideas that would be great.
I ended up using FindResource to locate the resource defined in the xaml resource document. This was specified in the project code I was referencing to, however FindResource was not working by itself, I needed to add App.Current:
notifyIcon = (TaskbarIcon)App.Current.FindResource("NotifyIcon");
notifyIcon.ShowBalloonTip(title, text, BalloonIcon.Error);

drag and drop winform controls

I want to drag and drop a control (label for example) in a winform application. I saw some examples on dragging and dropping text, but this is not what I want. I want to enable the user to move a control around. Can anyone direct me to some resources or examples? Thanks.
you should look at examples on how to make draggable controls.
There are some answers here in SO as well.
See this Move controls when Drag and drop on panel in C#
this is a complete example on how to host the Form Designer:
Tailor Your Application by Building a Custom Forms Designer with .NET
I did something similar in Delphi long time ago, will search the source code, convert it into .NET C# and make a wiki page on that matter, as it is becoming such popular question recently :)
As far as i understand, where you wish to drop a control is called a container, infact any control can act as a container. So first that container, you need to enable the drop property as well as the drag property of the controls which you need to drag.
Then write events (Candrag, candrop, controladded, etc.) for each control where in which, some logic to hold the objects and display them as you may want.
Say, ill take an example where in which, you wish to drag imagetext from combombox into a picturebox and then make the picturebox analyze the text and fine related file name in a directory and load that image into its if its present.
So here, when you start dragging the text from combombox, you have to write some logic in event candrag. Then once you drop, you have to write logic to understand what kinda object was added and get the text related to it (kinda deciphering) in the control where you drop other control.
Sorry, i have no code to give you now, but i hope you got the idea how its done. May be this article can help you? http://vicky4147.wordpress.com/2007/02/04/a-simple-drag-drop-in-winforms/
bool draging = false;
int curPosX, curPosY;
private void label2_MouseDown(object sender, MouseEventArgs e)
{
draging = true;
curPosX = Cursor.Position.X;
curPosY = Cursor.Position.Y;
}
private void label2_MouseMove(object sender, MouseEventArgs e)
{
if (draging)
{
label2.Left += Cursor.Position.X - curPosX;
curPosX = Cursor.Position.X;
label2.Top += Cursor.Position.Y - curPosY;
curPosY = Cursor.Position.Y;
}
}
private void label2_MouseUp(object sender, MouseEventArgs e)
{
draging = false;
}

Detect when a control on design surface is selected

I'm writing an Expression Blend 4 Extension and I want to detect (in my extension) when a Control or Element on the design surface is selected. Can someone tell me how I can detect it? Thanks, Tim
I've continued a bit on my tutorial on writing extensions. When you look at the sample code of this project the code below should be clear.
The first method below is called when the active document is changed. This method handles the ActiveDocumentChanged event of the IDocumentService. First it gets the content of TimelinePane from the palette registry. In this content lives the ActiveSceneViewModel. The ActiveSceneViewModel is the viewmodel that containse the active scene (= the current xaml file being edited). The ActiveSceneViewModel contains a set of the selected elements, the ElementSelectionSet. Which has an event(Changed) that is fired when it is changed. Handle this event.
In this eventhandler you'll have access to the selection set, directly after it is changed.
private void ActiveDocumentChanged(object sender, DocumentChangedEventArgs e)
{
var timelinePane =
(TimelinePane)WindowService.PaletteRegistry["Designer_TimelinePane"].Content;
_activeSceneViewModel = timelinePane.ActiveSceneViewModel;
_activeSceneViewModel.ElementSelectionSet.Changed +=
new System.EventHandler(ElementSelectionSet_Changed);
//some other goes here....
}
void ElementSelectionSet_Changed(object sender, System.EventArgs e)
{
SceneElementSelectionSet selectionSet
= sender as SceneElementSelectionSet;
// get the selected elements from the selection set
}

Categories

Resources