Is it possible to disable the keyboard controls for a Combobox in ZK?
That is, when a user enters some text into a Combobox, by default they can use the arrow keys to move up and down the list. I would like to disable this functionally as it doesn't work well with the user experience we are designing.
I see nothing in the documentation explicitly.
You can override _doKeyDown js function,
e.g.,
<zk xmlns:w="client">
<combobox>
<attribute w:name="_doKeyDown"><![CDATA[
function (evt) {
var keyCode = evt.keyCode;
if (keyCode != 38 && keyCode != 40) {
this.$_doKeyDown(evt);
}
}
]]></attribute>
<comboitem label="item one" />
<comboitem label="item two" />
<comboitem label="item three" />
</combobox>
</zk>
Related
I'm working with React.js and Carbon as Design System. I have a Tabs component with multiple Tab and I need to disable one of them if a condition is not satisfied.
I have tried to disable using the carbon class
className="bx--tabs__nav-item--disabled"
and also with prop disabled={true}but none of them works
There is some different way to disable the Tab element?? I know that avoid the onclick event works, but is no the prettiest way.
This is the code of the Tabs component.
<Tabs
tabContentClassName="tab-content"
className="tabs element-header__tabs"
>
<Tab
onClick={(e) =>
onclickHandler(e)
}
label="tab 1"
/>
<Tab
onClick={(e) =>
onclickHandler(e)
)
}
label="tab 2"
/>
<Tab
disabled={true}
onClick={(e) =>
onclickHandler(e)
)
}
label="tab 3"
/>
</Tabs>
For anyone else who stumbles across this...
disable={true}
Now works in the current version of Carbon Tabs. I'm not sure if it didn't work before but it does now...
https://www.carbondesignsystem.com/components/tabs/code
I have 2 buttons:
<Button Name="parent">
<StackPanel>
<Button Name="a" />
<Button Name="b" />
<Button Name="c" />
<Button Name="d" />
<Button Name="e" />
</StackPanel>
</Button>
Parent is registered to PreviewMouseLeftButtonDown event.
I want that the PreviewMouseLeftButtonDown event of the parent will not happen if we click on button c (c has some other registrations). I can't check it specifically (with GetPosition or to register to MouseEnter on c and change some flag...), because the parnet is generic one, and can contain many buttons.
I've tried to register PreviewMouseLeftButtonDown in c, but e.Handled = true isn't helping me, because the parent's event occurs before the child's one.
Is there any way to do it?
Thanks
that's because PreviewMouseLeftButtonDown uses a tunneling strategy , it hits the child last and the parent first ,
it sound like you need MouseLeftButtonDown in this case which uses a bubbling strategy and apply
e.IsHandled = true
when handling it from c ,
FYI ,for this reason e.IsHandled effects only child elements of you Button .
see RoutedEvents
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.
After opening a Popup menu programatically, if the user uses up and down arrow keys to move through the menu, menu items get highlighted and they never get unhighlighted. What can I do so that after the user presses the down arrow, the previously highlighted menuitem becomes unhighlighted?
This happens with a very simple Popup menu:
<Grid>
<Button x:Name="Button1" Content="Open Menu"
Click="OnPopupMenuButton_Click"
Height="23" HorizontalAlignment="Left" Margin="69,12,0,0" VerticalAlignment="Top" Width="75" />
<Popup x:Name="MyPopupMenu" StaysOpen="False" >
<StackPanel Orientation="Vertical" Background="White" Margin="0">
<MenuItem x:Name="xAimee" Header="Aimee" Margin="0,2,0,0" />
<MenuItem x:Name="xBarbara" Header="Barbara" />
<MenuItem x:Name="xCarol" Header="Carol" />
<Separator x:Name="xSeparator1" Margin="0,2,2,2"/>
<MenuItem x:Name="xDana" Header="Dana" />
<MenuItem x:Name="xElizabeth" Header="Elizabeth" />
</StackPanel>
</Popup>
</Grid>
Here is how the Popup gets opened:
private void OnPopupMenuButton_Click(object sender, System.Windows.RoutedEventArgs e)
{
Button button = sender as Button;
MyPopupMenu.PlacementTarget = button;
MyPopupMenu.Placement = PlacementMode.Mouse;
MyPopupMenu.IsOpen = true;
MyPopupMenu.StaysOpen = false;
}
I have been following up on archer's suggestion, but I had a few issues. First, I did not want the menu to open on a right-click, partly because I just didn't want it to open on a right-click and partly because I actually need to use PlacementMode.Top, and the context menu kept opening in the standard context-menu place (to the side and down).
So in the end, I did end up using a Context Menu, but I did a couple of special things. First, in the Window constructor, I set the button's ContextMenu to null, to prevent it from opening when right-clicked. Then when the user left-clicks, I programmatically set the ContextMenu to the one that I created in the xaml file. When the menu closes, I set the button's ContextMenu back to null. I tried manipulating the ContextMenu visibility instead, but that did not seem to work as well as setting it to null and back to an object.
Here is the final xaml, not too different from the question exception that I am handling the Closed event for the ContextMenu.
<Button x:Name="xOpenContextMenuButton" Content = "Open Menu"
Click="OnContextMenuButton_Click"
HorizontalAlignment="Right" VerticalAlignment="Bottom"
Width="80" Margin="0,0,36,8" Height="23">
<Button.ContextMenu>
<ContextMenu x:Name="xContextMenu" Closed="OnContextMenu_Closed">
<MenuItem x:Name="xAimee" Header="Aimee" />
<MenuItem x:Name="xBarbara" Header="Barbara" />
<MenuItem x:Name="xCarol" Header="Carol" />
<Separator x:Name="xSeparator1" Margin="0,2,2,2" />
<MenuItem x:Name="xDana" Header="Dana" />
<MenuItem x:Name="xElizabeth" Header="Elizabeth" />
</ContextMenu>
</Button.ContextMenu>
</Button>
Here is the code-behind, which changed a lot:
public MainWindow()
{
InitializeComponent();
xOpenContextMenuButton.ContextMenu = null;
}
private void OnContextMenuButton_Click(object sender, System.Windows.RoutedEventArgs e)
{
xOpenContextMenuButton.ContextMenu = xContextMenu;
xContextMenu.PlacementTarget = xOpenContextMenuButton;
xContextMenu.Placement = PlacementMode.Top;
xContextMenu.IsOpen = true;
xContextMenu.StaysOpen = false;
}
private void OnContextMenu_Closed(object sender, RoutedEventArgs e)
{
xOpenContextMenuButton.ContextMenu = null;
}
Once again, thanks to archer, because I didn't realize that using Popup was not the normal way to create a popup menu in WPF. I think the root cause of the problem is, a Popup can contain anything -- a label, another button, etc. Popup isn't necessarily expecting embedded MenuItems, so it isn't smart enough to understand that it should switch between my menu items when using the arrow keys. But a ContextMenu expects to have MenuItems in it so it knows how to switch between them.
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>