Как считывать динамически изменяющиеся значения с помощью программы чтения с экрана в метке в приложении WPF? - PullRequest
0 голосов
/ 07 октября 2018

У меня есть приложение WPF, которое печатает от 1 до 50 чисел, и XAML, и код приведены ниже.Мое требование - считывать значения меток с помощью программы чтения с экрана NVDA каждый раз, когда устанавливается новый контент.Мой вопрос заключается в том, как добиться считывания содержимого, которое изменяется динамически?Не могли бы вы помочь мне достичь этого?Спасибо

Мой XAML

<Window x:Class="WPFAccessibility.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WPFAccessibility"
        mc:Ignorable="d"
        Title="WPFAccessibility" Height="450" Width="800">
    <Grid>
        <Label Name="progressLabel" FontSize="20" Margin="50,50"></Label>
    </Grid>
</Window>

Мой код файла

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Threading;

namespace WPFAccessibility
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            var mySource = Enumerable.Range(1, 50).ToList();
            Task.Factory.StartNew(() => DoOperation(mySource));
        }

        private void DoOperation(List<int> values)
        {
            foreach (var i in values)
            {
                Thread.Sleep(1000);
                var currentProgress = i;
                Dispatcher.BeginInvoke(new Action(() =>
                {
                    Process(currentProgress);

                }), DispatcherPriority.Background);
            }
        }

        private void Process(int currentProgress)
        {
            progressLabel.Content = "Processing...   " + currentProgress;

            if (currentProgress == 50)
                progressLabel.Content = "Processing completed.";
        }
    }
}

Ответы [ 2 ]

0 голосов
/ 08 октября 2018

Я использовал AutomationProperties.LiveSetting = "Polite" в элементе управления Label и в разделе кода, который я создал AutomationPeer , чтобы поднять PropertyChanged событие для UIA .Эта функция LiveSettings доступна только для .NET Framework 4.7.1 и более поздних версий.

XMAL

<Window x:Class="WPFAccessibility.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WPFAccessibility"
        mc:Ignorable="d"
        Title="WPFAccessibility" Height="450" Width="800">
    <Grid>
        <Label Name="progressLabel" FontSize="20" Margin="50,50" AutomationProperties.LiveSetting="Polite"></Label>
    </Grid>
</Window>

Код

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Threading;
namespace WPFAccessibility
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        private static int counter = 0;
        public MainWindow()
        {
            InitializeComponent();

            var mySource = Enumerable.Range(1, 50).ToList();
            Task.Factory.StartNew(() => DoOperation(mySource));
        }

        private void DoOperation(List<int> values)
        {
            foreach (var i in values)
            {
                Thread.Sleep(2000);
                var currentProgress = i;
                Dispatcher.BeginInvoke(new Action(() =>
                {
                    Process(currentProgress);

                }), DispatcherPriority.Background);
            }
        }

        private void Process(int currentProgress)
        {
            progressLabel.Content = "Processing...   " + currentProgress;

            if (currentProgress == 50)
                progressLabel.Content = "Processing completed.";

            var peer = UIElementAutomationPeer.FromElement(progressLabel);
            if (peer == null)
                peer = UIElementAutomationPeer.CreatePeerForElement(progressLabel);
            peer.RaiseAutomationEvent(AutomationEvents.LiveRegionChanged);  
        }       
    }
}
0 голосов
/ 07 октября 2018

Я, вероятно, должен был бы это как комментарий к вашему вопросу, но я думаю, что это могло бы помочь привести вас к правильному ответу, поэтому вместо этого хотел опубликовать в качестве ответа.Я понимаю, что доступность связана с веб-приложениями, но у меня нет опыта работы с приложениями WPF, но, возможно, это сходство поможет.

В html вы можете использовать свойство aria-live элемента, чтобы при изменении текста внутри него об этом было объявлено.Вы можете контролировать, будет ли анонсирован только небольшой фрагмент текста, который изменился, или будет объявлен весь элемент.

Например:

<span aria-live="true">You have <span id="timeleft">X</span> seconds left</span>

Если «timeleft» изменяется на 5,программа чтения с экрана просто объявит «5».Но это, вероятно, не будет иметь смысла, просто услышав «5».Вы можете использовать свойство aria-atomic, чтобы прочитать весь текст.(«Атомная» означает «одна единица»)

<span aria-live="true" aria-atomic="true">You have <span id="timeleft">X</span> seconds left</span>

Теперь, когда X изменяется на 5, программа чтения с экрана скажет «У вас осталось 5 секунд».Весь элемент <span> читается.

Итак, как это связано с вашим первоначальным вопросом?Вы должны быть в состоянии использовать свойства автоматизации, чтобы сделать что-то подобное.В частности, свойство LiveSetting.Несмотря на то, что этому блогу, « .NET Framework 4.7.1 Специальные возможности и улучшения WPF », исполнился год (сентябрь 2017 г.), он содержит несколько полезных сведений о свойстве LiveSetting.

...