Merge pull request #839 from mono/more-wpf-accessibility

More WPF accessibility changes
This commit is contained in:
Jérémie Laval 2018-08-09 18:21:01 -04:00 коммит произвёл GitHub
Родитель 3187770c01 1244cdde46
Коммит e30a4a39dc
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
17 изменённых файлов: 392 добавлений и 52 удалений

Просмотреть файл

@ -62,6 +62,11 @@ namespace Xwt.GtkBackend
Initialize (backend?.Widget, eventSink);
}
public void Initialize (IPopoverBackend parentPopover, IAccessibleEventSink eventSink)
{
// Not currently supported
}
public void Initialize (object parentWidget, IAccessibleEventSink eventSink)
{
this.eventSink = eventSink;

Просмотреть файл

@ -74,6 +74,15 @@ namespace Xwt.GtkBackend
ApplicationContext.InvokeUserCode (EventSink.OnColorChanged);
}
public Xwt.Drawing.Color TextColor {
get {
throw new NotImplementedException ("Gtk ColorSelector doesn't currently support the TextColor property");
}
set {
throw new NotImplementedException ("Gtk ColorSelector doesn't currently support the TextColor property");
}
}
public Xwt.Drawing.Color Color {
get {
var xwtColor = Widget.CurrentColor.ToXwtValue ();

Просмотреть файл

@ -5,6 +5,8 @@ using System.Text;
using System.Windows;
using System.Windows.Automation;
using System.Windows.Automation.Peers;
using System.Windows.Controls.Primitives;
using System.Windows.Media;
using Xwt.Accessibility;
using Xwt.Backends;
@ -18,24 +20,59 @@ namespace Xwt.WPFBackend
public bool IsAccessible { get; set; }
private string identifier;
public string Identifier {
get { return AutomationProperties.GetAutomationId (element); }
set { AutomationProperties.SetAutomationId (element, value); }
set {
identifier = value;
AutomationProperties.SetAutomationId (element, value);
}
}
private string label;
public string Label {
get { return AutomationProperties.GetName (element); }
set { AutomationProperties.SetName (element, value); }
set {
label = value;
AutomationProperties.SetName (element, value);
}
}
private string description;
public string Description {
get { return AutomationProperties.GetHelpText (element); }
set { AutomationProperties.SetHelpText (element, value); }
set {
description = value;
AutomationProperties.SetHelpText (element, value);
}
}
private Widget labelWidget;
public Widget LabelWidget {
set {
labelWidget = value;
AutomationProperties.SetLabeledBy (element, (Toolkit.GetBackend (value) as WidgetBackend)?.Widget);
}
}
/// <summary>
/// In some cases (just Popovers currently) we need to wait to set the automation properties until the element
/// that needs them comes into existence (a PopoverRoot in the case of a Popover, when it's shown). This is
/// used for that delayed initialization.
/// </summary>
/// <param name="element">UIElement on which to set the properties</param>
public void InitAutomationProperties (UIElement element)
{
if (identifier != null)
AutomationProperties.SetAutomationId (element, identifier);
if (label != null)
AutomationProperties.SetName (element, label);
if (description != null)
AutomationProperties.SetHelpText (element, description);
if (labelWidget != null)
AutomationProperties.SetLabeledBy (element, (Toolkit.GetBackend (labelWidget) as WidgetBackend)?.Widget);
}
public string Title { get; set; }
public string Value { get; set; }
public Role Role { get; set; } = Role.Custom;
@ -59,6 +96,13 @@ namespace Xwt.WPFBackend
wpfBackend.HasAccessibleObject = true;
}
public void Initialize (IPopoverBackend parentPopover, IAccessibleEventSink eventSink)
{
var popoverBackend = (PopoverBackend) parentPopover;
Popup popup = popoverBackend.NativeWidget;
Initialize (popup, eventSink);
}
public void Initialize (object parentWidget, IAccessibleEventSink eventSink)
{
this.element = parentWidget as UIElement;

Просмотреть файл

@ -1,4 +1,4 @@
//
//
// BoxBackend.cs
//
// Author:
@ -139,9 +139,13 @@ namespace Xwt.WPFBackend
}
}
public AutomationPeer AutomationPeerOverride { get; set; }
protected override AutomationPeer OnCreateAutomationPeer ()
{
return new CustomPanelAutomationPeer (this);
if (AutomationPeerOverride != null)
return AutomationPeerOverride;
else return new CustomPanelAutomationPeer (this);
}
class CustomPanelAutomationPeer : FrameworkElementAutomationPeer

Просмотреть файл

@ -1,4 +1,4 @@
//
//
// DropDownButton.cs
//
// Author:
@ -28,7 +28,9 @@ using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Automation;
using System.Windows.Automation.Peers;
using System.Windows.Automation.Provider;
using System.Windows.Controls.Primitives;
using SWC = System.Windows.Controls;
@ -117,10 +119,13 @@ namespace Xwt.WPFBackend
return new DropDownButtonAutomationPeer (this);
}
class DropDownButtonAutomationPeer : ToggleButtonAutomationPeer
class DropDownButtonAutomationPeer : ButtonBaseAutomationPeer, IExpandCollapseProvider
{
public DropDownButtonAutomationPeer (DropDownButton owner) : base (owner)
DropDownButton owner;
public DropDownButtonAutomationPeer (DropDownButton owner) : base(owner)
{
this.owner = owner;
}
// Don't go into the children of this element
@ -128,6 +133,44 @@ namespace Xwt.WPFBackend
{
return null;
}
protected override string GetClassNameCore ()
{
return nameof(DropDownButton);
}
///
override protected AutomationControlType GetAutomationControlTypeCore ()
{
return AutomationControlType.Button;
}
///
override public object GetPattern (PatternInterface patternInterface)
{
if (patternInterface == PatternInterface.ExpandCollapse)
return this;
else
return base.GetPattern (patternInterface);
}
public void Expand ()
{
owner.IsChecked = true;
}
public void Collapse ()
{
owner.IsChecked = false;
}
public ExpandCollapseState ExpandCollapseState {
get {
if (owner.IsChecked == null)
return ExpandCollapseState.Collapsed;
else return (bool)owner.IsChecked ? ExpandCollapseState.Expanded : ExpandCollapseState.Collapsed;
}
}
}
}
}

Просмотреть файл

@ -1,4 +1,4 @@
//
//
// ExTreeViewItem.cs
//
// Author:
@ -26,7 +26,10 @@
// THE SOFTWARE.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Automation.Peers;
using System.Windows.Controls;
using System.Windows.Input;
using SWC = System.Windows.Controls;
@ -230,12 +233,38 @@ namespace Xwt.WPFBackend
//We can't allow TreeViewItem(our base class) to get this message(OnGotFocus) because it will also select this item which we don't want
}
private bool CtrlPressed
{
get
{
return Keyboard.IsKeyDown (WKey.RightCtrl) || Keyboard.IsKeyDown (WKey.LeftCtrl);
}
}
private bool CtrlPressed
{
get
{
return Keyboard.IsKeyDown (WKey.RightCtrl) || Keyboard.IsKeyDown (WKey.LeftCtrl);
}
}
protected override AutomationPeer OnCreateAutomationPeer ()
{
return new ExTreeViewItemAutomationPeer (this);
}
class ExTreeViewItemAutomationPeer : TreeViewItemAutomationPeer
{
public ExTreeViewItemAutomationPeer (ExTreeViewItem owner) : base (owner)
{
}
protected override List<AutomationPeer> GetChildrenCore ()
{
List<AutomationPeer> defaultChildren = base.GetChildrenCore ();
if (defaultChildren == null)
return null;
// We only want to include TreeView items in the a11y tree, not their constituent image/text/etc controls -
// for one thing including all controls messes up the "item 3 of 5" style counts announced by the
// narrator, as those controls would be include
List<AutomationPeer> children = defaultChildren.Where (
child => child is TreeViewItemAutomationPeer || child is TreeViewDataItemAutomationPeer).ToList ();
return children;
}
}
}
}

Просмотреть файл

@ -1,4 +1,4 @@
//
//
// PopoverBackend.cs
//
// Author:
@ -28,6 +28,7 @@ using System;
using Xwt.Backends;
using System.Windows.Media;
using System.Windows;
using System.Windows.Input;
namespace Xwt.WPFBackend
{
@ -54,14 +55,46 @@ namespace Xwt.WPFBackend
get; set;
}
/// <summary>
/// Control, if any, that should get the initial keyboard focus when the popover is shown.
/// The control should be inside the popover, but it doesn't necessarily have to be an Xwt
/// managed widget.
/// </summary>
public UIElement InitialFocus { get; set; }
/// <summary>
/// If set to true, then the arrow keys can't be used to move focus between controls.
/// Regardless of this setting, tab still works to change focus and the arrow keys still
/// work inside of controls that use them.
/// </summary>
public bool DisableArrowKeyNavigation { get; set; }
new Popover Frontend {
get { return (Popover)base.frontend; }
}
System.Windows.Controls.Primitives.Popup NativeWidget {
public System.Windows.Controls.Primitives.Popup NativeWidget {
get; set;
}
/// <summary>
/// Search up the visual tree, finding the PopupRoot for the popup.
/// </summary>
/// <returns>PopupRoot or null if not found for some reason</returns>
public FrameworkElement GetPopupRoot ()
{
FrameworkElement element = Border;
do {
element = (FrameworkElement) VisualTreeHelper.GetParent (element);
if (element == null)
return null;
if (element.GetType ().Name == "PopupRoot")
return element;
} while (true);
}
public PopoverBackend ()
{
Border = new System.Windows.Controls.Border {
@ -86,7 +119,9 @@ namespace Xwt.WPFBackend
Placement = System.Windows.Controls.Primitives.PlacementMode.Custom,
StaysOpen = false,
};
NativeWidget.Opened += NativeWidget_Opened;
NativeWidget.Closed += NativeWidget_Closed;
NativeWidget.PreviewKeyDown += NativeWidget_PreviewKeyDown;
}
public void Initialize (IPopoverEventSink sink)
@ -113,6 +148,27 @@ namespace Xwt.WPFBackend
};
NativeWidget.PlacementTarget = (System.Windows.FrameworkElement)Context.Toolkit.GetNativeWidget (reference);
NativeWidget.IsOpen = true;
// Popups are special in that the automation properties need to be set on the PopupRoot, which only exists when the popup is shown
// See https://social.msdn.microsoft.com/Forums/vstudio/en-US/d4ba12c8-7a87-478e-b064-5620f929a0cf/how-to-set-automationid-and-name-for-popup?forum=wpf
var accessibleBackend = (AccessibleBackend)Toolkit.GetBackend (Frontend.Accessible);
if (accessibleBackend != null) {
FrameworkElement popupRoot = GetPopupRoot ();
if (popupRoot != null)
accessibleBackend.InitAutomationProperties (popupRoot);
}
}
void NativeWidget_Opened (object sender, EventArgs e)
{
if (DisableArrowKeyNavigation) {
FrameworkElement popupRoot = GetPopupRoot ();
if (popupRoot != null)
KeyboardNavigation.SetDirectionalNavigation (popupRoot, KeyboardNavigationMode.Once);
}
if (InitialFocus != null)
InitialFocus.Focus ();
}
void NativeWidget_Closed (object sender, EventArgs e)
@ -121,6 +177,15 @@ namespace Xwt.WPFBackend
EventSink.OnClosed ();
}
void NativeWidget_PreviewKeyDown (object sender, System.Windows.Input.KeyEventArgs e)
{
// Close the popup when Escape is hit
if (e.Key == System.Windows.Input.Key.Escape) {
NativeWidget.IsOpen = false;
e.Handled = true;
}
}
public void Hide ()
{
NativeWidget.IsOpen = false;
@ -129,8 +194,10 @@ namespace Xwt.WPFBackend
public void Dispose ()
{
if (NativeWidget != null)
if (NativeWidget != null) {
NativeWidget.Opened -= NativeWidget_Opened;
NativeWidget.Closed -= NativeWidget_Closed;
}
}
}
}

Просмотреть файл

@ -1,4 +1,4 @@
//
//
// ValuesContainer.cs
//
// Author:
@ -67,5 +67,16 @@ namespace Xwt.WPFBackend
if (handler != null)
handler (this, e);
}
/// <summary>
/// ToString is used by the default ComboBoxItem automation peer to get the automation Name for the item.
/// Normally, we want to be the same as the text in the combo, the first value.
/// </summary>
public override string ToString ()
{
if (values.Length > 0 && values[0] is string)
return (string) values[0];
else return base.ToString ();
}
}
}

Просмотреть файл

@ -1,4 +1,4 @@
//
//
// WindowsSpinButton.cs
//
// Author:
@ -157,7 +157,7 @@ namespace Xwt.WPFBackend
#region General
Grid mainGrid;
TextBox textBox;
SpinButtonTextBox textBox;
RepeatButton buttonUp;
RepeatButton buttonDown;
public WindowsSpinButton()
@ -169,7 +169,7 @@ namespace Xwt.WPFBackend
mainGrid.ColumnDefinitions.Add(new ColumnDefinition() { Width = new GridLength(16) });
//Textbox
textBox = new TextBox();
textBox = new SpinButtonTextBox (this);
textBox.Text = "0";
textBox.HorizontalAlignment = HorizontalAlignment.Stretch;
textBox.MinWidth = 25;
@ -247,6 +247,7 @@ namespace Xwt.WPFBackend
}
}
public TextBox TextBox => textBox;
private void UserControl_Loaded(object sender, RoutedEventArgs e)
{
@ -458,11 +459,27 @@ namespace Xwt.WPFBackend
#endregion
#region Accessibility
protected override AutomationPeer OnCreateAutomationPeer ()
{
return new WindowsSpinButtonAutomationPeer (this);
}
class SpinButtonTextBox : TextBox
{
WindowsSpinButton spinButton;
public SpinButtonTextBox (WindowsSpinButton spinButton)
{
this.spinButton = spinButton;
}
protected override AutomationPeer OnCreateAutomationPeer ()
{
return UIElementAutomationPeer.FromElement (spinButton);
}
}
class WindowsSpinButtonAutomationPeer : UserControlAutomationPeer, IRangeValueProvider
{
public WindowsSpinButtonAutomationPeer (WindowsSpinButton owner) : base (owner)
@ -486,6 +503,21 @@ namespace Xwt.WPFBackend
return AutomationControlType.Spinner;
}
protected override bool IsKeyboardFocusableCore ()
{
return Button.IsEnabled;
}
protected override bool HasKeyboardFocusCore ()
{
return Button.IsKeyboardFocusWithin;
}
protected override void SetFocusCore ()
{
Button.TextBox.Focus ();
}
public override object GetPattern (PatternInterface patternInterface)
{
if (patternInterface == PatternInterface.RangeValue) {

Просмотреть файл

@ -49,6 +49,11 @@ namespace Xwt.Mac
Initialize (parentBackend?.Widget, eventSink);
}
public void Initialize (IPopoverBackend parentPopover, IAccessibleEventSink eventSink)
{
// Not currently supported
}
public void Initialize (object parentWidget, IAccessibleEventSink eventSink)
{
this.eventSink = eventSink;

Просмотреть файл

@ -1,4 +1,4 @@
//
//
// Accessible.cs
//
// Author:
@ -50,9 +50,12 @@ namespace Xwt.Accessibility
protected override void OnBackendCreated ()
{
var parentBackend = Parent.parentComponent?.GetBackend () as IWidgetBackend;
if (parentBackend != null)
Backend.Initialize (parentBackend, this);
object parentBackend = Parent.parentComponent?.GetBackend ();
if (parentBackend is IWidgetBackend)
Backend.Initialize ((IWidgetBackend) parentBackend, this);
else if (parentBackend is IPopoverBackend)
Backend.Initialize ((IPopoverBackend) parentBackend, this);
else
Backend.Initialize (Parent.parentNativeObject, this);
}
@ -72,6 +75,15 @@ namespace Xwt.Accessibility
backendHost.Parent = this;
}
internal Accessible (Popover parent)
{
if (parent == null)
throw new ArgumentNullException (nameof (parent));
parentComponent = parent;
backendHost = new AccessibleBackendHost ();
backendHost.Parent = this;
}
internal Accessible (object nativeParent)
{
if (nativeParent == null)
@ -276,6 +288,10 @@ namespace Xwt.Accessibility
{
}
public void Initialize (IPopoverBackend parentPopover, IAccessibleEventSink eventSink)
{
}
public void Initialize (object parentWidget, IAccessibleEventSink eventSink)
{
}

Просмотреть файл

@ -1,4 +1,4 @@
//
//
// AccessibleBackendHandler.cs
//
// Author:
@ -32,6 +32,8 @@ namespace Xwt.Backends
{
void Initialize (IWidgetBackend parentWidget, IAccessibleEventSink eventSink);
void Initialize (IPopoverBackend parentPopover, IAccessibleEventSink eventSink);
void Initialize (object parentWidget, IAccessibleEventSink eventSink);
bool IsAccessible { get; set; }

Просмотреть файл

@ -30,6 +30,7 @@ namespace Xwt.Backends
{
public interface IColorSelectorBackend: IWidgetBackend
{
Color TextColor { get; set; }
Color Color { get; set; }
bool SupportsAlpha { get; set; }
}

Просмотреть файл

@ -1,4 +1,4 @@
//
//
// ColorPicker.cs
//
// Author:
@ -120,7 +120,7 @@ namespace Xwt
}
}
class DefaultColorPickerBackend: XwtWidgetBackend, IColorPickerBackend
public class DefaultColorPickerBackend: XwtWidgetBackend, IColorPickerBackend
{
readonly Button colorButton;
readonly ColorImage colorImage;
@ -182,6 +182,8 @@ namespace Xwt
get { return (IColorPickerEventSink)base.EventSink; }
}
public Button ColorButton => colorButton;
public Color Color {
get {
return colorImage.Color;

Просмотреть файл

@ -27,6 +27,7 @@ using System;
using Xwt.Drawing;
using Xwt.Backends;
using System.Collections.Generic;
using Xwt.Accessibility;
namespace Xwt
@ -62,7 +63,15 @@ namespace Xwt
IColorSelectorBackend Backend {
get { return (IColorSelectorBackend) BackendHost.Backend; }
}
/// <summary>
/// Gets or sets the color to be used for labels and other UI text
/// </summary>
public Color TextColor {
get { return Backend.TextColor; }
set { Backend.TextColor = value; }
}
/// <summary>
/// Gets or sets the selected color
/// </summary>
@ -114,6 +123,7 @@ namespace Xwt
bool loadingEntries;
List<Widget> alphaControls = new List<Widget> ();
bool enableColorChangedEvent;
List<Label> labelWidgets = new List<Label> ();
public DefaultColorSelectorBackend ()
{
@ -137,49 +147,67 @@ namespace Xwt
const int entryWidth = 40;
VBox entryBox = new VBox ();
Table entryTable = new Table ();
entryTable.Add (new Label (Application.TranslationCatalog.GetString("Color:")), 0, 0);
entryTable.Add (CreateLabel (Application.TranslationCatalog.GetString("Color:")), 0, 0);
entryTable.Add (colorBox, 1, 0, colspan:4);
entryTable.Add (new HSeparator (), 0, 1, colspan:5);
int r = 2;
entryTable.Add (new Label (Application.TranslationCatalog.GetString("Hue:")), 0, r);
var hueLabel = CreateLabel ();
entryTable.Add (hueLabel, 0, r);
entryTable.Add (hueEntry = new SpinButton () {
MinWidth = entryWidth, MinimumValue = 0, MaximumValue = 360, Digits = 0, IncrementValue = 1 }, 1, r++);
entryTable.Add (new Label (Application.TranslationCatalog.GetString("Saturation:")), 0, r);
SetupEntry (hueEntry, hueLabel, Application.TranslationCatalog.GetString ("Hue"));
var satLabel = CreateLabel ();
entryTable.Add (satLabel, 0, r);
entryTable.Add (satEntry = new SpinButton () {
MinWidth = entryWidth, MinimumValue = 0, MaximumValue = 100, Digits = 0, IncrementValue = 1 }, 1, r++);
entryTable.Add (new Label (Application.TranslationCatalog.GetString("Light:")), 0, r);
SetupEntry (satEntry, satLabel, Application.TranslationCatalog.GetString ("Saturation"));
var lightLabel = CreateLabel ();
entryTable.Add (lightLabel, 0, r);
entryTable.Add (lightEntry = new SpinButton () {
MinWidth = entryWidth, MinimumValue = 0, MaximumValue = 100, Digits = 0, IncrementValue = 1 }, 1, r++);
SetupEntry (lightEntry, lightLabel, Application.TranslationCatalog.GetString ("Light"));
r = 2;
entryTable.Add (new Label (Application.TranslationCatalog.GetString("Red:")), 3, r);
var redLabel = CreateLabel ();
entryTable.Add (redLabel, 3, r);
entryTable.Add (redEntry = new SpinButton () {
MinWidth = entryWidth, MinimumValue = 0, MaximumValue = 255, Digits = 0, IncrementValue = 1 }, 4, r++);
entryTable.Add (new Label (Application.TranslationCatalog.GetString("Green:")), 3, r);
SetupEntry (redEntry, redLabel, Application.TranslationCatalog.GetString ("Red"));
var greenLabel = CreateLabel ();
entryTable.Add (greenLabel, 3, r);
entryTable.Add (greenEntry = new SpinButton () {
MinWidth = entryWidth, MinimumValue = 0, MaximumValue = 255, Digits = 0, IncrementValue = 1 }, 4, r++);
entryTable.Add (new Label (Application.TranslationCatalog.GetString("Blue:")), 3, r);
SetupEntry (greenEntry, greenLabel, Application.TranslationCatalog.GetString ("Green"));
var blueLabel = CreateLabel ();
entryTable.Add (blueLabel, 3, r);
entryTable.Add (blueEntry = new SpinButton () {
MinWidth = entryWidth, MinimumValue = 0, MaximumValue = 255, Digits = 0, IncrementValue = 1 }, 4, r++);
Label label;
SetupEntry (blueEntry, blueLabel, Application.TranslationCatalog.GetString ("Blue"));
entryTable.Add (alphaSeparator = new HSeparator (), 0, r++, colspan:5);
entryTable.Add (label = new Label (Application.TranslationCatalog.GetString("Opacity:")), 0, r);
var alphaLabel = CreateLabel ();
entryTable.Add (alphaLabel, 0, r);
entryTable.Add (alphaSlider = new HSlider () {
MinimumValue = 0, MaximumValue = 255, }, 1, r, colspan: 3);
entryTable.Add (alphaEntry = new SpinButton () {
MinWidth = entryWidth, MinimumValue = 0, MaximumValue = 255, Digits = 0, IncrementValue = 1 }, 4, r);
SetupEntry (alphaEntry, alphaLabel, Application.TranslationCatalog.GetString ("Opacity"));
// Don't allow the slider to get keyboard focus, as it doesn't really work with the keyboard and the opacity
// spin button takes its place
alphaSlider.CanGetFocus = false;
alphaSlider.Accessible.Label = Application.TranslationCatalog.GetString ("Opacity");
alphaControls.Add (alphaSeparator);
alphaControls.Add (label);
alphaControls.Add (alphaLabel);
alphaControls.Add (alphaEntry);
entryBox.PackStart (entryTable);
box.PackStart (entryBox);
Content = box;
@ -199,6 +227,37 @@ namespace Xwt
Color = Colors.White;
}
public Color TextColor {
get {
return labelWidgets[0].TextColor;
}
set {
foreach (Label labelWidget in labelWidgets)
labelWidget.TextColor = value;
}
}
static void SetupEntry (SpinButton spinButton, Label labelWidget, string labelText)
{
labelWidget.Text = GetLabelWithColon (labelText);
spinButton.Accessible.Label = labelText;
spinButton.Accessible.LabelWidget = labelWidget;
}
Label CreateLabel (string text = null)
{
Label label = text == null ? new Label () : new Label (text);
labelWidgets.Add (label);
return label;
}
static string GetLabelWithColon (string labelText)
{
string labelFormat = Application.TranslationCatalog.GetString ("{0}:");
return string.Format (labelFormat, labelText);
}
void HandleAlphaChanged (object sender, EventArgs e)
{
if (loadingEntries)

Просмотреть файл

@ -25,6 +25,7 @@
// THE SOFTWARE.
using System;
using Xwt.Accessibility;
using Xwt.Drawing;
using Xwt.Backends;
@ -44,6 +45,7 @@ namespace Xwt
WidgetSpacing padding;
Widget content;
bool shown;
Accessible accessible;
EventHandler closedEvent;
@ -84,7 +86,16 @@ namespace Xwt
VerifyConstructorCall (this);
Content = content;
}
public Accessible Accessible {
get {
if (accessible == null) {
accessible = new Accessible (this);
}
return accessible;
}
}
public Widget Content {
get { return content; }
set {

Просмотреть файл

@ -64,6 +64,7 @@ namespace Xwt
WidgetPlacement alignHorizontal = WidgetPlacement.Fill;
bool expandVertical;
bool expandHorizontal;
Accessible accessible;
EventHandler<DragOverCheckEventArgs> dragOverCheck;
EventHandler<DragOverEventArgs> dragOver;
@ -323,7 +324,6 @@ namespace Xwt
}
}
Accessible accessible;
public Accessible Accessible {
get {
if (accessible == null) {