2012-03-23 11 views
3

私はWPFフォームを2つの列のグリッドで構成しています。WPFでUserControlにアクセスできるようにする

左側にはコントロールラベルがあり、右側には自分のコントロールがあります。

コントロールはすべてUserControlsです。最も単純なケースでは、これらのコントロールのいくつかは、テキストボックスなどの既存のWPFコントロールを単純にまとめて、すべて共通のインターフェイスを実装します。

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

一つの問題:フォームが生成されると、私はnewControlは、ユーザーコントロールを作成し、ctl.Captionは、単に必要なラベルのテキストを返している関連する制御用のラベルを設定するには、このようなコードを持って

ターゲットが実際に動作しないという設定です。キャプションにアンダースコアがある場合、ニーモニックキーはラップされたコントロールにフォーカスを設定しません。これのための1つの回避策は、UserControlコード内のラップされたコントロールにフォーカスを手動で設定することです - しかし、...

最大の問題はアクセシビリティです。 JAWSやWindows組み込みナレータなどのスクリーンリーダーは、コントロールがフォーカスを受け取ったときにコントロールキャプションを読み取らない。

私はこれを見てきました:http://msdn.microsoft.com/en-us/library/windows/desktop/gg712258.aspx - 多くの詳細を提供しますが、役に立つ例はありません。それは約カスタムコントロールについては、多くのものを持っています簡単にユーザーコントロールのために過剰ですか?

私のラベルを正しくUserControlに「添付」するにはどうすればよいですか?

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> 

それは、WPFのテキストボックスクラスを拡張:

<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> 

と:

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で

だから私はあなたの問題は、あなたのUserControlで自分自身とそれらがどのように構築されている(例えば、どのようなテンプレート)

編集関係していると思います:

コントロールが既存のコントロールを拡張していない場合、には WPFコントロールが含まれている場合は、おそらくFocusメソッドに問題があります。コントロール自体にフォーカスが当たったときに、コントロールの右側にフォーカスを設定するFocus()メソッドを追加する必要があります。 (あなたは、インスタンスのためのフォーカスを取得したいテキストボックスを含むユーザーコントロール用)

コード:

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(); 
    } 
} 

背後

<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: 私は一度問題がありましたフォーカスを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

ダビッドに感謝、私はちょうどそれを与えてきましたが、それは効果がないようです。そして、それでもアクセシビリティは壊れています.Narratorまたは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; } } 
} 

、その後、あなたは私のように、Decoratorパターンを使用する

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

AddChildはContentControlで保護されているので、AddControlToGrid関数でアクセスすることはできません。そして、UserControlはパネルにキャストできません。さらに、ドキュメントからは、IAddChildが.net 4で廃止されているように見えます。 –

+0

あなたは正しいIAddChildは廃止されました。これはe ContentProperty属性に置き換えられました。それを聞いてくれてありがとう。 そして私は彼が彼のユーザコントロールをPanelにキャストすべきだと言っているのではなく、Panelのようなコンテンツを持つコントロールを使うことができます(抽象的で直接使うことはできません) –

関連する問題