How to get enclosing element of a ContextMenu, using sender - silverlight

I have a contextmenu that's located inside a grid. In the contextmenu's closed-event I need to get hold of the encapsulating grid. I'm aware that I can, in the newest silverlight toolkit, use:
var cm = sender as ContextMenu;
var grid = cm.Owner as Grid;
However, i want to solve it with my current (older) toolkit-version.
private void Contextmenu_Closed(object sender, RoutedEventArgs e)
{
// insert solution here
}
Does anyone know how i can achieve this?
Update: tried about everything, couldnt figure it out. Ended up installing the newest toolkit.

<toolkit:MenuItem Header="Add" Click="MenuItem_Click"/>
private void MenuItem_Click(object sender, RoutedEventArgs e)
{
MenuItem menuItem = (MenuItem)sender;
MessageBox.Show("You chose to " + menuItem.Header.ToString(),"Result",MessageBoxButton.OK);
}

Related

Insert Autocomplete textbox inside listview WPF

I want to insert autocomplete textboxes inside listview control in WPF.
well I downloaded a premade auto complete textbox from nugget called "WpfControls.AutoCompleteTextBox"
here's the code to add it:
private void button_Click_1(object sender, RoutedEventArgs e)
{
WpfControls.AutoCompleteTextBox TestTextBox = new WpfControls.AutoCompleteTextBox();
listView.Items.Add(TestTextBox);
}

WPF path shape title

I have a path shape, i want to set a label above the path ,i put a textblock above the path then i handle the Path_MouseEnter , Path_MouseLeave and change the path background the problem is when the mouse leave the path shape to textblock the background changed the other problem when i handle the Path_MouseDown , the textblock also make a problem is there a beter way to set a label above the path shape ?
private void Path_MouseEnter(object sender, MouseEventArgs e)
{
(sender as Path).Fill = System.Windows.Media.Brushes.Yellow;
}
private void Path_MouseLeave(object sender, MouseEventArgs e)
{
(sender as Path).Fill = System.Windows.Media.Brushes.LightGray;
}
private void Path_MouseDown(object sender, MouseButtonEventArgs e)
{
}
Your question is difficult to follow, but I think you mean that you have a TextBlock overlayed on top of a Path, and when the mouse hits the textblock, your Path_MouseLeave() is triggered but your don't want it to be?
If this is the case, just set IsHitTestVisible="False" on the TextBlock to make it transparent to mouse events.

It is possible to create "new MouseButtonEventArgs" in Silverlight?

I'm newbie in Silverlight and I need to activate MouseRightButtonDown(object sender, MouseButtonEventArgs e) from an another event handler in my application.
I have found, that in WPF it is possible to do somthing like this:
public void OnContextMenuOpened(object sender, RoutedEventArgs e) {
MouseButtonEventArgs args = new MouseButtonEventArgs(
InputManager.Current.PrimaryMouseDevice,
0,
MouseButton.Right);
MouseRightButtonDown(sender, args);
}
But I have in Silverlight neither InputManager-Class nor MouseButton-Class... It is generally possible to realise something like that?
I want to do it, because I try to select an DataGridRow(within an custom control) with help of right-mouse-button. Without context menu it is easily possible, but when I switch context menu on, then context menu opens and event will not fired...
My code snippet:
public override void OnApplyTemplate() {
DataGrid = (DataGrid)GetTemplateChild("DataGrid");
DataGrid.MouseRightButtonDown += DataGridMouseRightButtonDown;
ContextMenu = (ContextMenu)GetTemplateChild("ContextMenu");
ContextMenu.Opened += OnContextMenuOpened;
}
private void DataGridMouseRightButtonDown(object sender, MouseButtonEventArgs e) {
//My code to select an DataGridRow
}
public void OnContextMenuOpened(object sender, RoutedEventArgs e) {
//This event-handler now will be always activated if I do
//right-mouse-button-click
}
Thanks a lot for help!
The Results of my research has shown, that it is impossible in silverlight -.-

Avalon Dock Auto Hide problems on load

I am having a problem with Avalon Docking where my second panel that's docked at the bottom and set to AutoHide.
When UI runs the pane loads as Docked/Visible by default. I would like to have it hidden/minimized.
<ad:DockingManager>
<ad:ResizingPanel Orientation="Vertical">
<ad:DocumentPane>
<ad:DocumentContent>
<... data grid that fills the view>
</ad:DocumentContent>
<ad:DocumentPane>
<ad:DockablePane>
<ad:DockableContent Title="output" DockableStyle="AutoHide" IsCloseable="False">
<...some control>
I have tried various "hacks" suggested on Avalon forums, where OnLoad, you can
outputDockablePane.ToggleAutoHide();
and that works, meaning, when UI is loaded the pane is hidden. However, once you toggle auto hide in .cs code, clicking on the dock header at runtime to make the pane visible/float stops working. So you have to hook up DockingMananger.OnMouseUp() and parse through a couple of boolean states and manually call ToggleAutoHide() - I guess only on the time. Seems like a hack to me.
Here's what I am doing for now, till I find a proper and clean solution:
private void OnDockManagerLoaded(object sender, RoutedEventArgs e)
{
if(_firstTimeLoad && !_isDataGridLoaded)
{
outputDockablePane.ToggleAutoHide();
_forcedToAutoHide = true;
}
}
private void OnDockingManagerMouseUp(object sender, MouseButtonEventArgs e)
{
if (_forcedToAutoHide)
{
_forcedToAutoHide = false;
outputDockableContent.Activate();
outputDockablePane.ToggleAutoHide();
}
}
Is there a setting/property that I am totally missing, or/and a better way?
4 Years still Avalon Docking has the same issue .While I haven't found a proper solution yet , I have tried to refine you workaround logic.
private void OnDockingManagerMouseUp(object sender, MouseButtonEventArgs e)
{
if (outputDockableContent.IsAutoHidden)
{
outputDockableContent.IsActive = false;
}
}

Is there an MVVM-friendly way to use the WebBrowser control in WPF?

Thanks to this question (click me!), I have the Source property of my WebBrowser binding correctly to my ViewModel.
Now I'd like to achieve two more goals:
Get the IsEnabled property of my Back and Forward buttons to correctly bind to the CanGoBack and CanGoForward properties of the WebBrowser.
Figure out how to call the GoForward() and GoBack() methods without resorting to the code-behind and without the ViewModel having to know about the WebBrowser.
I have the following (non-working) XAML markup at the moment:
<WebBrowser
x:Name="_instructionsWebBrowser"
x:FieldModifier="private"
clwm:WebBrowserUtility.AttachedSource="{Binding InstructionsSource}" />
<Button
Style="{StaticResource Button_Style}"
Grid.Column="2"
IsEnabled="{Binding ElementName=_instructionsWebBrowser, Path=CanGoBack}"
Command="{Binding GoBackCommand}"
Content="< Back" />
<Button
Style="{StaticResource Button_Style}"
Grid.Column="4"
IsEnabled="{Binding ElementName=_instructionsWebBrowser, Path=CanGoForward}"
Command="{Binding GoForwardCommand}"
Content="Forward >" />
I'm pretty sure the problem is that CanGoBack and CanGoForward are not dependency properties (and don't implement INotifyChanged), but I'm not quite sure how to get around that.
Questions:
Is there any way to hook up attached properties (as I did with Source) or something similar to get the CanGoBack and CanGoForward bindings to work?
How do write the GoBackCommand and GoForwardCommand so they are independent of the code-behind and ViewModel and can be declared in markup?
For anyone who comes across this question and wants a complete solution, here it is. It combines all of the suggestions made in this thread and the linked threads (and others those link to).
XAML:
http://pastebin.com/aED9pvW8
C# class:
http://pastebin.com/n6cW9ZBB
Example XAML usage:
http://pastebin.com/JpuNrFq8
Note: The example assumes your view binds to a ViewModel that provides the source URL to the browser. A very rudimentary navigation bar with back, forward, and refresh buttons and address bar is provided just for demonstration.
Enjoy. I have set the expiration on those pastebin's to never, so they should be available for as long as pastebin exists.
I used this in my bindable webbrowser wrapper:
CommandBindings.Add(new CommandBinding(NavigationCommands.BrowseBack, BrowseBack, CanBrowseBack));
CommandBindings.Add(new CommandBinding(NavigationCommands.BrowseForward, BrowseForward, CanBrowseForward));
CommandBindings.Add(new CommandBinding(NavigationCommands.BrowseHome, GoHome, TrueCanExecute));
CommandBindings.Add(new CommandBinding(NavigationCommands.Refresh, Refresh, TrueCanExecute));
CommandBindings.Add(new CommandBinding(NavigationCommands.BrowseStop, Stop, TrueCanExecute));
Note that I created my bindable webbrowser as FrameworkElement that exposes DependencyProperties and calls methods on the actual browser element, so i can set CommandBindings on it.
That way, you can use the default NavigationCommands in your View.
The used handlers are:
private void CanBrowseBack(object sender, CanExecuteRoutedEventArgs e) {
e.CanExecute = webBrowser.CanGoBack;
}
private void BrowseBack(object sender, ExecutedRoutedEventArgs e) {
webBrowser.GoBack();
}
private void CanBrowseForward(object sender, CanExecuteRoutedEventArgs e) {
e.CanExecute = webBrowser.CanGoForward;
}
private void BrowseForward(object sender, ExecutedRoutedEventArgs e) {
webBrowser.GoForward();
}
private void TrueCanExecute(object sender, CanExecuteRoutedEventArgs e) { e.CanExecute = true; }
private void Refresh(object sender, ExecutedRoutedEventArgs e) {
try { webBrowser.Refresh(); }
catch (Exception ex) { PmsLog.LogException(ex, true); }
}
private void Stop(object sender, ExecutedRoutedEventArgs e) {
mshtml.IHTMLDocument2 doc = WebBrowser.Document as mshtml.IHTMLDocument2;
if (doc != null)
doc.execCommand("Stop", true, null);
}
private void GoHome(object sender, ExecutedRoutedEventArgs e) {
Source = new Uri(Home);
}
Your question seems to imply that in order to correctly implement an MVVM pattern you are not allowed to have any code-behind. But perhaps adding some code-behind to your view will make it much easier to hook it up with your view-model. You can add dependency properties to the view and let it listen for INotifyPropertyChanged events.

Resources