4

codeplexのWPFデータグリッドを使用しています。私はDatagridTemplateColumnを使用しており、各列のコンテンツを表示するためのデータテンプレートを作成しました。

ここで、datagridの任意のコントロールにフォーカスがあるときに、ユーザーにヘルプメッセージを表示する必要があります。このために私は装飾層を使用することを考えました。ComboBoxをロードしたイベントを使用して、そのadrornerレイヤーにアクセスしました。次に、ツールチップと同様に表示されるものを使用して、独自の装飾レイヤーを追加しました。以下はコードです。

        TextBox txtBox = (TextBox)comboBox.Template.FindName("PART_EditableTextBox", comboBox);
        if (txtBox == null)
            return;

        txtBox.ToolTip = comboBox.ToolTip;
        AdornerLayer myAdornerLayer = AdornerLayer.GetAdornerLayer(txtBox);
        Binding bind = new Binding("IsKeyboardFocused");
        bind.Converter = new KeyToVisibilityConverter();
        bind.Source = txtBox;
        bind.Mode = BindingMode.OneWay;
        PEAdornerControl adorner = new PEAdornerControl(txtBox);
        adorner.SetBinding(PEAdornerControl.VisibilityProperty, bind);

PEAdornerレイヤーはこれです::

  public class PEAdornerControl : Adorner
  {
    Rect rect;

    // base class constructor.
    public PEAdornerControl(UIElement adornedElement)
        : base(adornedElement)
    { }

    protected override void OnRender(DrawingContext drawingContext)
    {
          .....
    }
  }

ここで問題は次のとおりです。datagridでどのように表示されているかのスクリーンショットを添付しています。データグリッドに4行を超える場合は、問題ありません。以下はスクリーンショットです。

ヘルプテキストを修正する

データグリッドの行数が少ない場合、この装飾者はデータグリッド内に入り、ユーザーには表示されません。スクリーンショットは下にあります ハーフヘルプテキスト

この装飾レイヤーをDataGridの上に配置するにはどうすればよいですか?私を助けてください !!!

4

2 に答える 2

1

私はあなたの質問をもう一度見ましたが、これがあなたが必要とするものだと思います.

    TextBox txtBox = (TextBox)comboBox.Template.FindName("PART_EditableTextBox", comboBox);
    if (txtBox == null)
        return;

    txtBox.ToolTip = comboBox.ToolTip;

    //this is locating the DataGrid that contains the textbox
    DataGrid parent = FindParent<DataGrid>(this);

    //Get the adorner for the parent
    AdornerLayer myAdornerLayer = AdornerLayer.GetAdornerLayer(parent);
    Binding bind = new Binding("IsKeyboardFocused");
    bind.Converter = new KeyToVisibilityConverter();
    bind.Source = txtBox;
    bind.Mode = BindingMode.OneWay;
    PEAdornerControl adorner = new PEAdornerControl(txtBox);
    adorner.SetBinding(PEAdornerControl.VisibilityProperty, bind);

親の検索方法は次のとおりです。

public T FindParent<T>(DependencyObject obj) where T : DepedencyObject
{
  if (obj == null)
     return null;
  DependencyOBject parent = VisualTreeHelper.GetParent(obj);

  if (parent is T)
      return parent as T;
  else
      return FindParent<T>(parent);
 }

OnRender メソッドでアドナーの位置を設定する必要があるかもしれませんが、これは機能するはずです。ただし、考慮すべきことの 1 つは、DataGrid が別のコンテナー (パネル、グリッドなど) 内にある場合でも、クリッピングの問題が発生する可能性があることです。

クリッピングの問題は、コンテナーがその子のレイアウトをチェックするときに、通常はその装飾を考慮しないという事実によるものです。これに対抗するには、独自のコントロールを作成して MeasuerOverride(Size constraint) メソッドをオーバーライドする必要があります。

例:

public class MyPanel : Panel
{
   protected override Size MeasureOverride(Size constraint)
   {
     Size toReturn = new Size();
     foreach (UIElement child in this.InternalChildren)
     {
       //Do normal Measuring of children

       foreach( UIElement achild in AdornerLayer.GetAdorners(child))
       //Measure child adorners and add to return size as needed
     }

     return toReturn;
   }
 }

そのコードは測定するには非常に大雑把ですが、正しい方向を示しているはずです。パネル内の子要素の測定については、ドキュメント ページhttp://msdn.microsoft.com/en-us/library/system.windows.frameworkelement.measureoverride.aspxを参照してください。

于 2011-04-11T14:25:33.560 に答える
0

AdornerLayer代わりに、最上位を取得するだけです

    static AdornerLayer GetAdornerLayer(FrameworkElement adornedElement)
    {
        var w = Window.GetWindow(adornedElement);
        var vis = w.Content as Visual;

        return AdornerLayer.GetAdornerLayer(vis);
    }

また、自分の名前がある場合は、そのDataGrid上にある最も近いレイヤーを取得できます。

AdornerLayer myAdornerLayer = AdornerLayer.GetAdornerLayer(myDataGrid);
于 2016-01-31T23:15:32.457 に答える