MenuItem click only works when child item is clicked - wpf

I have a larger PowerShell Script that is importing XAML code into it. Here's part of the code:
XAML
<Menu x:Name="menu" DockPanel.Dock="Top">
<MenuItem x:Name="menuFile" Header="File">
<MenuItem x:Name="menuFile_History" Header="_History"/>
<MenuItem x:Name="menuFile_Recent" Header="_Recent">
<MenuItem x:Name="menuFile_Recent1"/>
<MenuItem x:Name="menuFile_Recent2"/>
<MenuItem x:Name="menuFile_Recent3"/>
<MenuItem x:Name="menuFile_Recent4"/>
<MenuItem x:Name="menuFile_Recent5"/>
</MenuItem>
<MenuItem x:Name="menuFile_ShowMore" Header="_Show More"/>
<MenuItem x:Name="menuFile_FlushDNS" Header="_Flush DNS"/>
<MenuItem x:Name="menuFile_KillProcess" Header="Kill Process"/>
<Separator/>
<MenuItem x:Name="menuFile_Close" Header="_Close"/>
</MenuItem>
<MenuItem x:Name="menuEdit" Header="Edit">
<MenuItem x:Name="menuEdit_ConvertIP" Header="Convert IP" IsCheckable="True" IsChecked="True"/>
</MenuItem>
<MenuItem x:Name="menuHelp" Header="Help">
<MenuItem x:Name="menuHelp_About" Header="About"/>
</MenuItem>
</Menu>
PowerShell
$menuFile.Add_Click({
$txtInput.Text = "It worked!"
})
The problem is that the above PowerShell code is only ran when one of the child items is clicked, not when $menuFile is clicked. I have looked and looked and I cannot figure out why this is happening and how to fix it.
Thank you very much.

You're looking for a different event handler than Click. You want GotFocus or something like that.Try this instead
$menuFile.Add_GotFocus({$txtInput.Text = "It worked!"})
You can check out all of the events you can add event handlers to by piping to Get-Member as such:
$menuFile | Get-Member -MemberType Methods -force |?{$_.Name -like 'add*'}
Then just look for the methodsJust for kicks I tried this, and it worked as expected:
$menuFile.Add_GotFocus({$menuFile.FontSize = 16})
$menuFile.Add_LostFocus({$menuFile.FontSize = 12})
Then when I clicked on the File menu the font size for it and its children got larger, but when I moved to a different menu or clicked away the font size shrank back to font size 12.

Related

React material ui sticky select all in top of the list

I want to add "select all" option to material ui multiselect which is always show on top of the list even if I have many records and i need to scroll down - like sticky header. I found a solutionhow to add select all but i don't know how to make this option always visible on top. Any ideas?
I ran into something similar, but I needed both a sticky top and bottom. The way I accomplished this was by using the default basic menu. From there, I put all of my MenuItem items within a MenuList. Now you can add whatever you want above or below the MenuList as either your sticky top or bottom. In order to get the middle section (MenuList) to scroll and to ensure the "sicky" parts below and above, ensure that the MenuList element has a set height and overflow y set to scroll. As long as the limiting height in the CSS is less than enough space for the elements to fit it should force the scroll. Here's an example built off the default Material UI one.
In a nutshell this is the minimum you're looking for.
SCSS
.overflow-y-scroll{
overflow-y: scroll;
}
.height-limit{
// You want this to be smaller than the amount of space
// the MenuItem items take up to force the scroll
height: 300px;
}
TSX
<Menu>
id="basic-menu"
anchorEl={anchorEl}
open={open}
onClose={handleClose}
MenuListProps={{
"aria-labelledby": "basic-button"
}}
>
// Start - Location for sticky headers
<h3>Sticky Top - Can be div or whatever</h3>
// NOTE: Without the CSS on this outer MenuList element
// it will not work. It doesn't have to be a MenuList it could
// even be a div so long as it has the appropriate CSS.
<MenuList className="overflow-y-scroll height-limit">
// Start - Location scrollable data
<MenuItem onClick={handleClose}>Profile</MenuItem>
<MenuItem onClick={handleClose}>My account</MenuItem>
<MenuItem onClick={handleClose}>Logout</MenuItem>
<MenuItem onClick={handleClose}>Profile</MenuItem>
<MenuItem onClick={handleClose}>My account</MenuItem>
<MenuItem onClick={handleClose}>Logout</MenuItem>
<MenuItem onClick={handleClose}>Profile</MenuItem>
<MenuItem onClick={handleClose}>My account</MenuItem>
<MenuItem onClick={handleClose}>Logout</MenuItem>
<MenuItem onClick={handleClose}>Profile</MenuItem>
<MenuItem onClick={handleClose}>My account</MenuItem>
<MenuItem onClick={handleClose}>Logout</MenuItem>
</MenuList>
// End- Location scrollable data
// Start - Location for sticky footers
<button type="button">Sticky Bottom</button>
// End - Location for sticky footers
</Menu>
I didn't make it pretty but did want to show a quick screenshot of what functionally it looks like.
Screenshot of drop down with Sticky Header and Footer

Set the initial value to material ui select

I have a TextField in Material UI used as Select. The MenuItems are working fine in the form, but I'm not being able to pre select an option based on data on a state previously populated
I have this , and as example I want to preselect "Familia 3" , What I'm supposed to set up?
<Textfield id="family" select value=0 defaultValue=3 >
<MenuItem value="0">Seleccionar</MenuItem>
<MenuItem value="1">Familia 1</MenuItem>
<MenuItem value="2">Familia 2</MenuItem>
<MenuItem value="3">Familia 3</MenuItem>
</TextField>
I tried changing Value, DefaultValue , removing one of them, and couldt find a solution
AI bet is very simple but I cant find any solution to show up with option "Familia 3" preselected
Can you help me with this?
Thanks !
Default value is not applicable in the select TextField
set your initial value as the value prop.
You have misspelling in the Textfield opening tag it should be TextField
when assigning a non string value to an attribute always use curly brackets ie: value={3}
<TextField id="family" select value={3}>
<MenuItem value="0">Seleccionar</MenuItem>
<MenuItem value="1">Familia 1</MenuItem>
<MenuItem value="2">Familia 2</MenuItem>
<MenuItem value="3">Familia 3</MenuItem>
</TextField>
You can store Familia 3 into the state and than set the value of text field to state
const [initial value, setinitialvalue ] = use state("Familia
3")
<Textfield id="family" select value={initialValue}
onChange={(e) => setinitialvalue(e.target.value) }
defaultValue=3 >
<MenuItem value="Seleccionar
">Seleccionar</MenuItem>
<MenuItem value="Familia 1">Familia 1</MenuItem>
<MenuItem value="Familia 2 ">Familia 2</MenuItem>
<MenuItem value="Familia 3">Familia 3</MenuItem>
</TextField>

Button inside a MenuItem won't open Sub-MenuItems

I have a Button inside a MenuItem.Header like this:
<Menu>
<MenuItem>
<MenuItem.Header>
<Button>Hello</Button>
</MenuItem.Header>
<MenuItem Header="SubItem1"/>
<MenuItem Header="SubItem2"/>
</MenuItem>
</Menu>
if I click the MenuItem outside the Button, the sub-menu opens. But if I click the Button the sub-menu will not open. I believe that's because the event of the clicked is not passed to the MenuItem. How do I fix it?
In short - I want the sub-menu to open when clicking the Button.
(The use is mainly for styling purposes, I have a button style and I want to use it as a MenuItem)
A Button doesn't know how to expand a MenuItem unless you tell it how to by writing some code:
<Menu>
<MenuItem>
<MenuItem.Header>
<Button Click="Button_Click">Hello</Button>
</MenuItem.Header>
<MenuItem Header="SubItem1"/>
<MenuItem Header="SubItem2"/>
</MenuItem>
</Menu>
private void Button_Click(object sender, RoutedEventArgs e)
{
Button btn = (Button)sender;
MenuItem mi = btn.Parent as MenuItem;
if (mi != null)
mi.IsSubmenuOpen = !mi.IsSubmenuOpen;
}

Dynamically bound menu

i'm noobie on WPF.
i have this Admin menu include 'manage A','manage B','manage C'
in my XAML
<MenuItem Header="_Admin" Name="adminMenuItem" Visibility="{Binding Path=IsAdmin, Mode=OneWay,}" >
<MenuItem Header="manage A" Command="ShowTab" />
<MenuItem Header="manage B" Command="ShowTab" />
<MenuItem Header="manage C" Command="ShowTab" />
</MenuItem>
in my mainWindow.cs code,
private void ShowTab(MenuItem menuItem)
{
if (menuItem.Header = "manage A")
showTabA();
if (menuItem.Header = "manage B")
showTabB();
if (menuItem.Header = "manage C")
showTabC();
}
can i bind menuitem with commands like that? if not, what's the best way to get the value from different menu items.
Many thanks
Specify a CommandParameter in the MenuItems which identifies the tab, and get that value from the ExecutedRoutedEventArgs.Parameter property, it's cleaner than using the header at the very least.

How do get menu to open to the left in WPF?

I have a menu (with menuitems) in WPF. Unfortunately when I click on the menu heading it opens the menu to the right. The problem is that there is stuff on the right that I don't want it to overlap. How do I tell WPF to open the menu to the left? Do I need to do a control template? (control templates seem so heavy handed for such basic style changes).
Thanks!
KSG
While you can create a ControlTemplate to do this like they do here, I agree that it is a cumbersome method just to modify one value on a part of the MenuItems. Instead, I think that this is a great place to use an AttachedProperty. We can create something just like the ContextMenuService, but for Popups (In fact, I'm somewhat surprised that it isn't built in).
To change where the popup is opening, we're going to want to set the Popup's PlacementMode. We can use the propa shortcut to generate our AttachedProperty(or properties if you want to implement the rest). We need to add a callback to our PropertyMetadata, but if the AttachedProperty is set inline on the control in XAML then the callback will fire before the whole control is fully constructed. To ensure the MenuItem's template is applied, and the Popup exists before we try and set it's value, we can just attach to the Loaded event if it isn't already loaded.
Once it is loaded, we want to retrieve the Popup from the template, and if we look at the MenuItem class we can see that it has a TemplatePartAttribute defining the Popup's name as "PART_Popup". Once we have that, we can set the PlacementMode on the MenuItem's Popup.
public static PlacementMode GetMenuPlacement(DependencyObject obj)
{
return (PlacementMode)obj.GetValue(MenuPlacementProperty);
}
public static void SetMenuPlacement(DependencyObject obj, PlacementMode value)
{
obj.SetValue(MenuPlacementProperty, value);
}
// Using a DependencyProperty as the backing store for MenuPlacement. This enables animation, styling, binding, etc...
public static readonly DependencyProperty MenuPlacementProperty =
DependencyProperty.RegisterAttached("MenuPlacement",
typeof(PlacementMode),
typeof(Window1),
new FrameworkPropertyMetadata(PlacementMode.Bottom, FrameworkPropertyMetadataOptions.Inherits, new PropertyChangedCallback(OnMenuPlacementChanged)));
private static void OnMenuPlacementChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
{
var menuItem = o as MenuItem;
if (menuItem != null)
{
if (menuItem.IsLoaded)
{
SetPopupPlacement(menuItem, (PlacementMode)e.NewValue);
}
else
{
menuItem.Loaded += new RoutedEventHandler((m, v) => SetPopupPlacement(menuItem, (PlacementMode)e.NewValue));
}
}
}
private static void SetPopupPlacement(MenuItem menuItem, PlacementMode placementMode)
{
Popup popup = menuItem.Template.FindName("PART_Popup", menuItem) as Popup;
if (popup != null)
{
popup.Placement = placementMode;
}
}
Now that we have our AttachedProperty, it's easy to change the Popup placement in the UI.
<Menu>
<MenuItem Header="Item 1"
local:Window1.MenuPlacement="Right">
<MenuItem Header="SubItem 1" />
<MenuItem Header="SubItem 2" />
<MenuItem Header="SubItem 3" />
<MenuItem Header="SubItem 4" />
</MenuItem>
<MenuItem Header="Item 2"
local:Window1.MenuPlacement="Left">
<MenuItem Header="SubItem 5" />
<MenuItem Header="SubItem 6" />
<MenuItem Header="SubItem 7" />
<MenuItem Header="SubItem 8" />
</MenuItem>
<MenuItem Header="Item 3"
local:Window1.MenuPlacement="Mouse">
<MenuItem Header="SubItem 9" />
<MenuItem Header="SubItem 10" />
<MenuItem Header="SubItem 11" />
<MenuItem Header="SubItem 12" />
</MenuItem>
</Menu>

Resources