2012-03-23 5 views
3

두 개의 열로 구성된 WPF 양식이 있습니다.WPF에서 UserControls에 액세스 가능하게 만들기

왼쪽 열에는 컨트롤 레이블이 표시되고 오른쪽 열에는 내 컨트롤이 있습니다.

컨트롤은 모두 UserControls입니다. 가장 단순한 경우, 이러한 컨트롤 중 일부는 텍스트 상자와 같은 기존 WPF 컨트롤을 간단하게 래핑하여 모든 인터페이스가 공통 인터페이스를 구현합니다.

Label newLabel = new Label(); 
newLabel.Content = ctl.Caption + ":"; 
newLabel.Target = newControl; 

하나의 문제 : 양식이 생성되면, 내가 newControl이 UserControl을 생성 ctl.Caption 단순히 필요한 레이블 텍스트를 반환 연결된 컨트롤에 대한 레이블을 설정하려면이 같은 코드를

대상 설정이 실제로 작동하지 않는다는 것입니다. 캡션에 밑줄이 있으면 니모닉 키가 래핑 된 컨트롤에 포커스를 설정하지 않습니다. 한 가지 해결 방법은 수동으로 UserControl 코드 내에서 래핑 된 컨트롤에 포커스를 설정할 수 있습니다. 그러나 ...

가장 큰 문제는 접근성입니다. JAWS 및 Windows 내장 내레이터와 같은 스크린 리더는 컨트롤이 포커스를받을 때 컨트롤 캡션을 읽지 않습니다.

많은 세부 정보를 제공하지만 도움이되는 예제가없는 http://msdn.microsoft.com/en-us/library/windows/desktop/gg712258.aspx을 살펴 보았습니다. 그것은 대략 사용자 정의 컨트롤에 대해 많은 것들을 가지고 있습니다. 이는 간단히 과장되어서 사용자 컨트롤입니까?

그래서 내 레이블을 올바르게 UserControls에 "부착"할 수 있습니까?

http://quest.codeplex.com/SourceControl/changeset/view/676933506953에서 전체 프로젝트 코드를 탐색 할 수 있습니다. 특정 코드는 EditorControls 프로젝트에 있으며 UserControls는 ElementEditor.xaml.cs에서 인스턴스화됩니다.

+0

내가 장식 패턴을 사용하는 것이 사용할 수 있습니다, 등 XAML에서 컨트롤을 '감쌀'수 있습니다 (즉, 사용자 지정 컨트롤을 만들 필요가 없습니다). 나는 일을 마치고 오늘 예를 올릴 것이다. – Dennis

답변

0

hmmm 작은 테스트 프로젝트에서 문제를 재현하려고했지만 나에게 그것은 효과가 있습니다 ... 그래서 당신은 userControls가 어떻게 만들어 졌는지에 대해 더 자세히 설명해야 할 것입니다. (평소처럼, 그냥 응용 프로그램 및 윈도우 파일)

내가 빈 프로젝트를 만들어 내 창에서 2 열이있는 그리드를 설정 : 여기에 나를 위해 작동 무엇

<Window x:Class="Test.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     Title="MainWindow" 
     Name="Window" 
     SizeToContent="WidthAndHeight"> 

    <Grid Name="MyGrid"> 
     <Grid.ColumnDefinitions> 
      <ColumnDefinition Width="100" /> 
      <ColumnDefinition Width="100"/> 
     </Grid.ColumnDefinitions> 
    </Grid> 

</Window> 

는 다음의 UserControl을 생성

<TextBox x:Class="Test.MyTextBox" 
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
      mc:Ignorable="d" 
      d:DesignHeight="300" d:DesignWidth="300"> 

</TextBox> 

하고 : 즉 WPF 입력란 클래스 확장

System.Windows를 사용하는 단계; using System.Windows.Controls;

namespace Test 
{ 
    public partial class MyTextBox : TextBox 
    { 
     public static readonly DependencyProperty CaptionProperty = 
      DependencyProperty.Register("Caption", typeof(string), typeof(MyTextBox), new UIPropertyMetadata("")); 
     public string Caption 
     { 
      get { return (string)GetValue(CaptionProperty); } 
      set { SetValue(CaptionProperty, value); } 
     } 

     public MyTextBox() 
     { 
      InitializeComponent(); 
     } 
    } 
} 

기본적으로 "캡션"dp가있는 텍스트 상자입니다.뒤에 내 윈도우의 코드에서

지금 :

public MainWindow() 
{ 
    InitializeComponent(); 

    MyTextBox tb = new MyTextBox { Caption = "_Foo", Width = 100 }; 
    Label lb = new Label { Content = tb.Caption + ":", Target = tb }; 

    MyGrid.Children.Add(lb); 
    MyGrid.Children.Add(tb); 

    Grid.SetColumn(lb, 0); 
    Grid.SetColumn(tb, 1); 
} 

이와

, 나는 ALT + F (심지어 "푸"의 F 아래 _ 볼 수 있습니다를 누를 때 TB에 포커스를 취득 할 라벨의 경우 누르기 ALT)

그래서 나는 당신의 문제를 생각은 당신의 UserControls와 함께 자신을 할 수있다 그리고 그들은 (내장하는 방법을 어떤 예를 들어 템플릿)

편집 :

,

컨트롤이 기존 컨트롤을 확장하지 않고 WPF 컨트롤이있는 경우 문제는 아마도 Focus 메서드에 있습니다. 컨트롤 자체가 포커스를 얻었을 때 컨트롤의 오른쪽 부분에 포커스를 설정하는 Focus() 메서드를 추가해야합니다.

코드는 (당신이 인스턴스에 대한 포커스를 취득하고자하는 텍스트 상자가 포함 된 UserControl을 위해) :

<TextBox x:Class="Test.MyTextBox" 
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
      mc:Ignorable="d" 
      d:DesignHeight="300" d:DesignWidth="300"> 

    <Grid> 
     <Grid.ColumnDefinitions> 
      <ColumnDefinition /> 
      <ColumnDefinition /> 
     </Grid.ColumnDefinitions> 

     <Button Content="foo" Grid.Column="0" /> 
     <TextBox Name="TextBoxPart" Grid.Column="1" /> 
    </Grid> 

</TextBox> 

코드 2 편집

public partial class MyTextBox : TextBox 
{ 
    public static readonly DependencyProperty CaptionProperty = 
     DependencyProperty.Register("Caption", typeof(string), typeof(MyTextBox), new UIPropertyMetadata("")); 
    public string Caption 
    { 
     get { return (string)GetValue(CaptionProperty); } 
     set { SetValue(CaptionProperty, value); } 
    } 

    public MyTextBox() 
    { 
     InitializeComponent(); 
    } 

    protected override void OnGotFocus(RoutedEventArgs e) 
    { 
     TextBoxPart.Focus(); 
    } 
} 

뒤에 : 를 내가 한 번 문제가 있었다 , dataGridCell의 하위 컨트롤에 포커스를 전송하려면 여기를 클릭하십시오.

<ControlTemplate.Triggers> 
    <Trigger Property="IsFocused" Value="True"> 
      <Setter TargetName="TextBoxPart" Property="FocusManager.FocusedElement" Value="{Binding ElementName=TextBoxPart}" /> 
    </Trigger> 
</ControlTemplate.Triggers> 

이 템플릿에 추가 할 수 있습니다. 초점을 잘 옮겨야합니다. 접근성에 대한 같은

, 난이 도움이 될 것입니다 생각하지 않습니다,하지만 난 당신이 원하는 것을 달성 어떤 식 으로든 표시되지 않습니다 : -/

+0

제 경우에는 기존의 컨트롤을 확장하지 않고 그냥 래핑합니다. 그래서 어쩌면 내가 예를 들어 일부 * MyCustomTextBoxControl 수 있습니다 * 텍스트 상자, 포함 할 수 있지만 그것을 파생하지 않습니다 (어쩌면 또한 단추 또는 뭔가 옆에 있기 때문에) –

+0

내 생각을 편집 한 다음 – David

+0

데이비드에게 감사 드려요. 나는 그 일을 한 번 해 봤지만 효과가없는 것 같습니다. 그리고 그때에도 접근성은 여전히 ​​깨져 있습니다. 내레이터 또는 JAWS를 사용할 때 텍스트 상자에 초점을 맞추면 레이블 캡션이 읽히지 않습니다. –

1

귀하의 newControl 유형 컨트롤입니다 당신을 허용하지 않습니다 추가 콘텐츠를 추가하십시오. 콘텐츠를 추가하려는 경우 ContentControl 또는 Panel (여러 자식)에 대해 IAddChild 인터페이스를 구현하는 자체 컨트롤을 구현할 수있는 것과 같이 지원하는 클래스를 사용해야합니다.

당신을위한 간단한 해결책은 문제가 될 수있다 :

<UserControl x:Class="UIMocks.MyCustomControl" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> 
    <StackPanel x:Name="content"/> 
</UserControl> 
코드 숨김

[ContentProperty("Children")] 
public partial class MyCustomControl : UserControl 
{ 
    public MyCustomControl() 
    { 
     InitializeComponent(); 
    } 

    public UIElementCollection Children { get { return content.Children; } } 
} 

한 다음

MyCustomControl newControl = InitialiseEditorControl(ctl); 
... 
Label newLabel = new Label(); 
newLabel.Content = ctl.Caption + ":"; 
newControl.Children.Add(newLabel); 
+0

AddChild는 ContentControl에서 보호되므로 AddControlToGrid 함수에서 액세스 할 수 없습니다. 그리고 UserControl을 Panel로 형변환 할 수 없습니다. 또한, 그것은 설명서에서 나타납니다. 넷에서 더 이상 사용되지 않는 IAddChild가 나타납니다. –

+0

맞습니다. IAddChild는 이제 폐기되었으며 e ContentProperty 특성으로 대체되었습니다. 그것을 주셔서 감사합니다. 그리고 저는 Panel에 usercontrol을 전달해야한다고 말하려고하지 않았습니다. Panel과 같은 내용을 가진 컨트롤을 사용할 수 있다고 말하면서 (이는 추상적이고 직접 사용할 수 없습니다) –

관련 문제