Change visual state with button - c#

I'm currently developing an app on UWP platform, even though its not of high importance since its school work only, I wish to make some smooth transitions at menu opening. I made two states of menu but I just can't figure out how to change state when "open menu" button is pressed, does anyone have any idea how to do that?
BTW menu is an StackPanel, hope I choose it rights
Thanks for your time

I believe this should do the trick:
Add these to the owning window/page/control:
xmlns:i="using:Microsoft.Xaml.Interactivity"
xmlns:core="using:Microsoft.Xaml.Interactions.Core"
And set the button as such:
<Button x:Name="TheButton"
Content="Transition">
<i:Interaction.Behaviors>
<core:EventTriggerBehavior EventName="Click">
<core:GoToStateAction StateName="TheStateToMoveTo"
TargetObject="{Binding ElementName=NameOfTheObjectWithTheStates}"
UseTransitions="True" />
</core:EventTriggerBehavior>
</i:Interaction.Behaviors>
</Button>
The event should be caught by the trigger and the behavior should make the state transition occur.

Related

Stop Screen Reader to read my control type in WPF

I have an old WPF application with needs and accessibility features. The application uses radio buttons to construct a menu with a popup.
The problem is the user doesn't want the narrator to say "radio button" when it's clicked. I am using AutomationProperties.HelpText and AutomationProperties.Name to adjust the text for the controls. I have no idea how to change the "ControlType" the narrator reads out when the control is in focus.
<RadioButton
AutomationProperties.AcceleratorKey="1"
AutomationProperties.AccessKey="3"
AutomationProperties.AutomationId="2"
AutomationProperties.HelpText="Taufiq"
AutomationProperties.ItemStatus="Test"
AutomationProperties.ItemType="Text"
AutomationProperties.Name="Take Snapshot"
Command="{Binding TakeSnapshotCommand}">
<StackPanel Orientation="Horizontal">
<ContentControl Content="{DynamicResource GalleryIcon}" Focusable="False" />
<TextBlock Text="Take Snapshot" />
</StackPanel>
</RadioButton>
None of the properties of the AutomationProperties works.
My understanding is that narrator will read the advertised type so that someone relying on the screen reader knows how to interact with the focussed item.
If you really need to control how this works, you'll need to subclass RadioButton and override OnCreateAutomationPeer to create your own peer which can then gain quite a bit of control.

WPF modal dialog on touch screen

I am using a custom modal dialog in a WPF application, that will run on a touch device (Windows 10). I am using the MVVM pattern.
My problem:
I experience different touch behavior depending on from where the dialog is opened. If it is opened from, for example, a button event handler or via button command binding, everything works fine. Then dialog buttons (typically "OK" and "Cancel") closes the dialog on first touch. But when the dialog is opened from code (not driven by button event or button command binding), the dialog buttons does not respond on the first touch. I then need to touch somewhere in the dialog before touching the button. It is kind of annoying.
I have a view model with an ExitCommand implemented that opens the dialog. Some XAML examples:
This works fine:
<Button Content="Exit" Command="{Binding ExitCommand}"/>
This does not work satisfactory:
<Label Content="Exit">
<Label.InputBindings>
<MouseBinding Gesture="LeftClick" Command="{Binding ExitCommand}"/>
</Label.InputBindings>
</Label>
And as mentioned, opening the dialog from code without any user action, does not work either.
Clues, anyone?
I'm not sure that this solution will solve your problem but try this please:
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
<Label Content="Exit">
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseDown">
<!-- MouseDown trigger for touch down too. -->
<i:InvokeCommandAction Command="{Binding ExitCommand}"
x:Name="exitCommandMouse" />
</i:EventTrigger>
</i:Interaction.Triggers>
</Label>
I use a similar solution with grid (instead label) and its works perfectly with touch screen on win 8.1.

Add Drag&Drop with Behaviors

I need to modify a desktop application which uses WPF, MVVM and Behaviors for event handling. I've got a task to implement Drag&Drop for a button. If the user presses the button it will popup a file-save window but if the user clicks and drags it, it should display a file icon and the let the user drop it into an Explorer window to save it there.
I've already added namespaces:
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:behaviors="clr-namespace:MyApplication.Desktop.Client.Behaviors"
xmlns:core="using:Microsoft.Xaml.Interactions.Core"
xmlns:command="http://www.galasoft.ch/mvvmlight"
I've also added XAML code into the button:
<Button Grid.Column="2"
Command="{Binding SaveAttachmentCommand}"
Visibility="{Binding RelativeSource={RelativeSource Self}, Path=IsEnabled, Converter={StaticResource boolToVisibilityConverter}}"
Style="{StaticResource AttachmentSaveButtonStyle}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="PreviewMouseLeftButtonDown">
<command:EventToCommand Command="{Binding LeftMouseButtonDownCommand}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
<i:Interaction.Behaviors>
<behaviors:FrameworkElementDragBehavior>
</behaviors:FrameworkElementDragBehavior>
</i:Interaction.Behaviors>
</Button>
But I don't know how to tell the behavior class (FrameworkElementDragBehavior) which events to handle and how to handle them (what functions to call).
I've read some tutorials but I'm still confused.
I had to do Drag and drop with MVVM two months ago.
After some research, personnaly, the best way to achieve that is to work with the "GongSolutions DragDrop" library.
It's very simple and it's perfect for what you're looking for.
For example, in a treeview:
<TreeView ItemsSource="{Binding LstCat}"
dd:DragDrop.IsDragSource="True"
dd:DragDrop.IsDropTarget="True"
dd:DragDrop.DragAdornerTemplate="{StaticResource DragAdorner}">
//Treeview Structure
</TreeView>
From there you can do Drag&Drop in the treeview. You can add a dragAdorner too (an image next to your pointer when you are dragging something)
In the viewModel you can tell the behaviour of the dragging or Dropping by implementing an interface which comes with the library. This way you can access to the data your dragging.
For example:
public void DragOver(IDropInfo dropInfo)
{
if (dropInfo.Data is Category && dropInfo.TargetItem is Rubrique)
{
return;
}
dropInfo.DropTargetAdorner = DropTargetAdorners.Highlight;
dropInfo.Effects = DragDropEffects.Move;
}
Here is the link of the library if you're interested:
https://github.com/punker76/gong-wpf-dragdrop

WinRT application login by pressing Enter key with MVVM light

I'm developing an application in which the user needs to enter a username and password to login.
I'm using the MVVM light framework to separate my view from my viewmodels.
For now I have a button on my view which tapped event is caught on the corresponding viewmodel.
I would also would like to have the possibility if the user presses the enter button they can also login. In WPF you had the ability to set a button as IsDefault, but it seems not possible in WinRT.
How can I do this?
I think you can put this code into your viewmodel and check if the enter key is pressed, then when it is pressed just launch the same method you would launch if your button was pressed
Windows.UI.Xaml.Window.Current.CoreWindow.KeyDown += (sender, arg) =>
{
if (arg.VirtualKey == Windows.System.VirtualKey.Enter)
{
//Your login method
}
};
As per my comment I don't recommend using UI code in the view model. Use a trigger to bind to a command for a keypress in the textbox.
<TextBox>
<i:Interaction.Triggers>
<i:EventTrigger EventName="KeyDown">
<cmd:EventToCommandCommand="{Binding MyCommand}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</TextBox>
be sure to incluide the following in your xaml declarations:
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
xmlns:cmd="http://www.galasoft.ch/mvvmlight"
Hope this helps
There's a virtual method on the Page called OnKeyDown() you can override. This is safer than subscribing to events and fits MVVM better. I prefer to cast DataContext to my view model type and call whatever I want.
It is possible to achieve this with behaviors:
<interactivity:Interaction.Behaviors>
<core:EventTriggerBehavior EventName="KeyDown">
<core:CallMethodAction TargetObject="{Binding}" MethodName="Load" />
</core:EventTriggerBehavior>
</interactivity:Interaction.Behaviors>
You'll have to reference:
xmlns:interactivity="using:Microsoft.Xaml.Interactivity"
xmlns:core="using:Microsoft.Xaml.Interactions.Core"
However, it only works for all keys. I didn't see any possibility to filter for a certain key.
There are:
xmlns:i="using:WinRtBehaviors"
xmlns:b="using:Win8nl.Behaviors"
<i:Interaction.Behaviors>
<b:EventToCommandBehavior Event="Loaded" Command="LoadedCommand"/>
</i:Interaction.Behaviors>
from Nuget.

Disabled context menu won't disappear after rightclick

I have a ContextMenu as part of a TabControl such as:
<TabControl Name="MyTabControl">
<TabControl.ContextMenu>
<ContextMenu Name="MyContextMenu" IsEnabled="False" StaysOpen="True">
<MenuItem Header="Item1"></MenuItem>
...
</ContextMenu>
</TabControl.ContextMenu>
</TabControl>
As you can see, the menu is disabled. It will be enabled later in the program, for now however, it should remain in its disabled state. The problem is, when I right-click the TabControl and the disabled menu shows, it simply stays where it was first opened, no other right-click will move it, nor will a left-click somewhere make it disappear.
The only way to get rid of it, would be either by enabling it and then right/left-clicking, or by using MyContextMenu.Visibility = Visibility.Collapsed/Hidden;
I tried setting the StaysOpen-property to False. Then the menu will open once in its disabled state. After left-clicking disappear and then not appear again even if it gets enabled.
The only way around it could be changing the StaysOpen-property along with the IsEnabled-property, but it is a bit weird that the menu opens exactly once in its disabled state and then not anymore.
I hope anybody could explain to me, why exactly a disabled menu won't close and the property StaysOpen at false makes it open exactly once, because it seems like a weird behaviour to me.
It seems that the behaviour of context menu items is quite strange - what you've described is in .Net 4.0 and if you target yor app to .Net 3.5 for instance you will notice the opposite behaviour - you can't make the menu stay opened if the single item is disabled, it just disappears immediately after it shows on right click.
However I think the preferrable way to manage the enabled state of a context menu item (and also the OnClick action it should do) is by a Command.
First you should specify a datacontext for your view, let's say it is the class ViewModel.cs. Then create a command by implementing the ICommand interface, something like this:
public class MyCommand : ICommand
And then you have a CanExecute method which does exactly what it's name says - decides if the command can be executed or not. And the enabled state of the menu item also depends on the return value of this method. So you can keep it returning false as long as you need in and the menu will behave correctly and the menu item will be disabled. Then when you want you can make it return true (by some logic in the method itself) and you'll have again a properly working context menu with enabled menu item.
If you want to disable the entire menu, use the same approach but for the menu.
And if you need to make all the items in the menu disabled (which I think is different from the entire menu), then you can use something like this:
<TabControl Name="MyTabControl" Background="Green">
<TabControl.ContextMenu>
<ContextMenu Name="MyContextMenu" StaysOpen="True" ItemsSource="{Binding Items}">
<ContextMenu.ItemTemplate>
<DataTemplate >
<MenuItem Header="{Binding Header}" IsEnabled="False" />
</DataTemplate>
</ContextMenu.ItemTemplate>
</ContextMenu>
</TabControl.ContextMenu>
</TabControl>
Here your ItemsSource (Items) is for instance List<MenuItem>, and MenuItem itselw would be your Model (thinking in MVVM) for each of your menu items, which should have property Header that contains the header you want to see in each menu item. Instead of setting the IsEnabled to false as in my dummy example, you can bind it to a property in order to have control on when it must be true and false.

Categories