Screen Reader reading disabled button's AutomationProperty.Id - c#

I've added a simple WPF window with two buttons in it.
The buttons are made visible by a certain logic and have bindings which change their Visibility and IsEnabled properties.
Now, I'm testing with windows navigator and seeing that the default windows navigator is reading about the buttons even when they are not visible.
How should I make the button not read by Screen Readers (or windows default navigator) when the button is disabled or not visible?
<Button Margin="0,0,80,10" Height="25" HorizontalAlignment="Right" Name="failedButton"
VerticalAlignment="Bottom" Width="75" DataContext="{Binding InstallationViewModel}"
Command="{Binding Failed}"
Visibility="{Binding Failed,
Converter={StaticResource BooleanToVisibilityConverter}}"
Content="Failed?" />

Automation api reads everything that provide a automation peer. So if you don't want your ui element expose to automation clients, you need to override OnCreateAutomationPeer and return null. And that means, you choose either support automation or not, but you can't change it at runtime.

Related

How to disable opening WPF popup

I have a Popup and a ToggleButton. I set a binding like this:
<ToggleButton x:Name="myToggle" Content="{Binding MyData.Title}" />
<Popup IsOpen="{Binding IsChecked, ElementName=myToggle}" >
<TextBlock Text="{Binding MyData.Details}" />
</Popup>
As you see, I bound the toggle button's content to MyData.Title and the popup's content to MyData.Details.
Now I had the criteria MyData.ShowDetails. If it is true the popup can open and if it is false the popup should not be opened.
How can I set a binding to achieve this?
I tested these bindings on the Popup but no one works:
Visibility="{Binding MyData.ShowDetails, Converter={StaticResource BooleanToVisibilityConverter}}"
IsEnable="{Binding MyData.ShowDetails}"
You could put a panel (Grid ) on top of all the content in your window.
That needs to have a background set but it can be low opacity if you still want to see the window content.
Make that visible only when the popup is shown and collapse otherwise.
Make sure you set focus to your popup when it's shown.
.
Bear in mind.
Popups are separate windows.
They are intended to be shown briefly and have a number of potential drawbacks if you show them for longer periods. EG other applications can appear under them and they don't move with their "parent" window/control.
You might find a modal window is easier and suits better, depending on your exact requirements.
Just instantiate a window and use
PopupWindow newWindow = new PopupWindow();
newWindow.ShowDialog();
Where PopupWindow is just any old window styled to look like you want the popup.
This will guarantee the user can't somehow interact with any other window in your app.
.
Another possibility is to show your "popup" content in a grid which appears on top of everything inside your main window.
That's how editing data works in this:
https://gallery.technet.microsoft.com/scriptcenter/WPF-Entity-Framework-MVVM-78cdc204
The plus or minus of that approach is that it's in the one window.
--- Brian Kress ---
I found a special answer in my case. Instead of disabling Popup, I should disable the ToggleButton:
<ToggleButton x:Name="myToggle" Content="{Binding MyData.Title}"
IsEnabled="{Binding MyData.ShowDetails}"/>
<Popup IsOpen="{Binding IsChecked, ElementName=myToggle}" >
<TextBlock Text="{Binding MyData.Details}" />
</Popup>
It works perfect!
Note: This is not a general answer for Popup. Welcome to anyone who has an answer.

How to handle Click event on a custom WPF control composed of controls that don't have Click events

I am creating a custom ToolBar control that I will be able to use in my WPF application.
My CustomToolBar control is based on a StackPanel control and will contain multiple CustomToolBarButton controls.
My CustomToolBarButtons are based on a vertical StackPanel and contain an Image control and a Label control.
I want to programmatically create a Click event for my CustomToolBarButtons that will fire when Image or label gets clicked. Unfortunately, neither Image nor Label controls have Click events in WPF.
It's a surprise for me because I am used to WinForms controls and vast majority of them have Click events by default. Do I have to create custom Image and Label controls and create Click events for them or is there a cleaner and simpler way of doing this?
Thanks for any help!
Well, there's not a great and simple way using standard functionality. I got around this by making my own trigger (derived from System.Windows.Interactivity.TriggerBase from the Blend SDK) so that in my projects I can do the following:
<Label>
<i:Interaction.Triggers>
<mu:MouseTrigger MouseButton="Middle" MouseAction="Click">
<i:InvokeCommandAction Command="{Binding Path=Close}" />
</mu:MouseTrigger>
</i:Interaction.Triggers>
</Label>
Effectively the MouseTrigger class will handle MouseDown and MouseUp events from the UIElement it's attached to and use that to invoke the actions associated with the trigger. The code is a bit more complex than just that, though, since I also do mouse capturing & I utilize an internal helper class so that I could add multiple triggers to the same element with only one instance of a helper class handling events & capturing the mouse for that element.
For the actual actions, I just use existing Blend or Prism actions such as InvokeCommandAction.
Here is the project if you're interested. It was too large to paste into this format. It uses some C# 6.0 features but you could easily modify it to work on an older version of C# by removing some null conditional operators. It requires you install the Blend SDK as it depends on System.Windows.Interactivity (should install with Visual Studio as long as you select that option). MouseTrigger is the publicly visible class that is the point of interaction with the functionality. MouseCatcher is the internal helper class mentioned.
I'd recommend not going down the route of custom controls, but rather of using some mechanism (this one or otherwise) to extend the existing functionality using the attached property framework that WPF and XAML bring to the table.
In WinForms you would create custom controls simply to get a nonstandard look, in WPF this is no longer necessary.
The WPF way: instead of making a Stackpanel's children implement Click behaviour, let's make a Button look like the desired Stackpanel.
Could do this setting the Content:
<Button>
<StackPanel >
<Image Source="C:\myFiles\myPic.png"/>
<Label HorizontalAlignment="Center">SomeTxt</Label>
</StackPanel>
</Button>
But this way it still looks like a Button, to overcome this we can set the Template instead:
<Button>
<Button.Template>
<ControlTemplate TargetType="Button">
<StackPanel >
<Image Source="C:\myFiles\myPic.png"/>
<Label HorizontalAlignment="Center">SomeTxt</Label>
</StackPanel>
</ControlTemplate>
</Button.Template>
</Button>
Both solutions will raise a Click event clicking the image or label.

Do I need dependency properties for all basic properties on my user control?

I am currently writing my first user control which would consist of a label and a text box in a stack panel like follows:
<Grid>
<StackPanel Orientation="Horizontal" DataContext="{Binding RelativeSource={RelativeSource Self}}">
<Label Content="{Binding Label}" Width="60"></Label>
<TextBox Text="{Binding TextBoxContent}" Width="60"/>
</StackPanel>
</Grid>
This will be most useful to be in a settings page, as it will be reused for several different settings. With each of these settings, I will want to set (at a minimum) the width, height, validation rule and error template properties. As for the text itself, I have already created a dependency property both for the label and the text box (as you can see in my snippet above).
My question is this: Do I need to create a dependency property for all of the properties I just mentioned that I would like to set when I actually use my user control? This seems like redundant work (since they already exist on the text box, basically they would just redirect my user control's property to the text box's property of the same name)? This is even more work if I want to use even more properties on my text box (for example, AcceptsReturn, etc).
The redundant work can be saved if you decide to derive from TextBox rather than UserControl - just think of your control as a "labeled textbox" and all you need to do is derive from TextBox and add the needed dependency properties to accommodate for the label. This of course would not be the case for more complex user controls, but it seems OK in your case.
The downside to this though is that you'll have to take the default control template for TextBox and work with it to add your label, which may be a bit trickier.
Either way, I recommend having a look at the Control Authoring Overview page on MSDN, which is extremely useful when writing your first controls in WPF.

How can i mark menuitem in Application Bar Windows Phone 7

How can i mark menuitem in Application Bar. I want to get, for example, this:
You can change the template of the MenuItem.Header, as described in this tutorial. For example:
<toolkit:ContextMenuService.ContextMenu>
<toolkit:ContextMenu>
<toolkit:MenuItem Header="AddItem"/>
<!-- a templated menu item -->
<toolkit:MenuItem>
<toolkit:MenuItem.Header>
<StackPanel Orientation="Horizontal">
<TextBlock Text="Delete Item"/>
<Image Source="Images/appbar.delete.rest.png"/>
</StackPanel>
</toolkit:MenuItem.Header>
</toolkit:MenuItem>
</toolkit:ContextMenu>
</toolkit:ContextMenuService.ContextMenu>
I'd say it can't be done. The menu items are just calls to functions and can do nothing but show the corresponding text and call the corresponding method when activated. I've found some examples of people hacking extra functionality into them (updating the text or changing the function calls, to some extent), but nothing beyond that would be possible.
Notice that what you can do with the AppBar is limited by the functionality offered by IApplicationBar and, in your case, ApplicationBarMenuItem. And none of them expose anything even close to your requirements.
You can, however, enable and disable menu items, although I don't think that's what you want.

c# WPF how to produce a flashy warning

I'm learning WPF, so bear with me.
I would like to have my WPF application flash in the user's face if a certain event is fired.
What is the best way to "notify" the user? I really want the user to react!
Cheers, Patrick
Environment: Windows7/64bit/.Net4
If you want the user to react you can force them to by simply opening a modal dialogue. The most lightweight of which being the MessageBox. You can also create normal modal windows using their ShowDialog method, you can make those windows as "fancy" as you want by getting rid of their normal appearance. This is achieved by setting the WindowStyle to None and AllowsTransparency to true, this will remove all the frame elements, so the window is now pure content.
Popups are handy for non-modal notifications and they already are content-only, but setting their AllowsTransparency to true may also be desired if you want rounded corners for example.
Best is entirely subjective and depends on many context variables but here is how I do it MVVM style.
In your main view model, define a property
pubic ObservableCollection<AlertViewModel"> Alerts { get; private set; }
in my case the AlertViewModel has only a "Message" property and a "Dismiss" RelayCommand.
In the XAML of your main view add
<Grid>
<all of my other other view controls>
<ItemsControl x:Name="AlertsControl" Opacity="50" ItemsSource="{Binding Alerts}"/>
</Grid>
Make sure it is the last item in the main container of your main view. This ensures it has the highest z order and will appear on top of all other controls.
Here is the data template for this view model
<DataTemplate DataType="{x:Type vm:AlertViewModel}">
<Border CornerRadius="10" Margin="3" Background="Red">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="75"></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
</Grid.ColumnDefinitions>
<Button Margin="10" Grid.Column="0"
Command="{Binding ElementName=theWindow, Path=DataContext.DismissAlarmCommand}"
CommandParameter="{Binding}">Dismiss</Button>
<TextBlock Foreground="White" FontWeight="ExtraBold" Grid.Column="1"
Text="{Binding Message}" FontSize="20"
VerticalAlignment="Center" HorizontalAlignment="Left"></TextBlock>
</Grid>
</Border>
</DataTemplate>
Now,
Alerts.Add( new AlertViewModel() { Message = "Danger Will Robinson! Danger!" } );
Will pop a Bright red alert box onto the top of your main form. It does not go away until the user presses "Dismiss"
If you want it to flash or fade in and out or bounce up and down you can add animation in the data template.
You can use a Converter or data to Enable/Disable the rest of the controls in the app byt binding to AlertsControl.HasItems
Good luck.

Categories

Resources