在WPF中,如何在DataGrid之上显示AdornerLayer [英] In WPF, how to display AdornerLayer on top of DataGrid

查看:254
本文介绍了在WPF中,如何在DataGrid之上显示AdornerLayer的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用来自codeplex的WPF数据网格。我正在使用DatagridTemplateColumn,我已经编写了datatemplates来显示每列中的内容。



现在,当datagrid中的任何控件被集中时,我必须向用户显示一些帮助消息。
为此我想到使用adorner图层。我使用ComboBox加载事件并访问它的adrorner层。然后我添加了我自己的adorner图层,有些东西要显示,类似于工具提示。以下是代码。

  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;

//基类构造函数。
public PEAdornerControl(UIElement adornedElement)
:base(adornedElement)
{}

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

现在的问题如下。我附带了如何查看datagrid的截图。如果datagrid有超过4行,事情很好。下面是截图





如果datagrid的行数较少,此adorner将进入数据网格,用户不可见。截图为



如何在DataGrid上方获得此adorner图层?请帮助我!!!

解决方案

我再次看了你的问题,我想这就是你需要的。

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

txtBox.ToolTip = comboBox.ToolTip;

//这是找到包含文本框的DataGrid
DataGrid parent = FindParent< DataGrid>(this);

//获取父项的adorner
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);

find parent方法是这样的:

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

if(parent为T)
返回父作为T;
else
return FindParent< T>(parent);
}

您可能需要在OnRender方法中设置您的adorner的位置,但这应该工作有一点需要考虑的是,如果您的DataGrid在另一个容器(如面板,网格等)中,那么您仍然可能遇到剪辑问题。



裁剪问题是由于事实是当一个容器检查其孩子的布局时,通常不会考虑他们的装饰。为了解决这个问题,您可能需要创建自己的控件并覆盖MeasuerOverride(Size约束)方法。



示例:

  public class MyPanel:Panel 
{
protected override Size MeasureOverride(Size constraint)
{
Size toReturn = new Size );
foreach(UIElement child in this.InternalChildren)
{
//做正常测量的孩子

foreach(UIElement achild在AdornerLayer.GetAdorners(child))
//测量儿童装饰品,并根据需要添加返回尺寸
}

返回到返回;
}
}

该代码对于度量而言非常粗糙,但应指出在正确的方向请参阅文档页面 http://msdn.microsoft。 com / en-us / library / system.windows.frameworkelement.measureoverride.aspx 了解有关在面板中测量子元素的信息。


I am using WPF datagrid from codeplex. I am using DatagridTemplateColumn and I have written datatemplates to display contents in each column.

Now I have to display some help message to a user when the any control in datagrid is focussed. For this I thought of using adorner layer. I used ComboBox loaded event and accessed the adrorner layer of it. I then added my own adorner layer with some thing to be displayed there similar to tooltip. Below is the code.

        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 layer is this ::

  public class PEAdornerControl : Adorner
  {
    Rect rect;

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

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

Now the problem is as follows. I am attaching screenshot of how it is looking in datagrid. If the datagrid has more than 4 rows, things are fine.Below is the screenshot

If the datagrid has less number of row, this adorner goes inside datagrid and is not visible to user. The screenshot is below

How do I get this adorner layer above the DataGrid? Please help me !!!

解决方案

I looked at your question again and i think this is what you would need.

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

The find parent method is this:

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

You may need to set the position of your adorner in the OnRender method but this should work. One thing to consider though is that if your DataGrid is within another container (such as a panel, grid, etc) then you may still run into your clipping problem.

The clipping problem is due to the fact that when a container checks the layout of its children it does not normally take into account their adorners. To combat this you would possibly need to create your own control and override the MeasuerOverride(Size constraint) method.

Example:

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

That code is really rough for measure but should point you in the right direction. Look at the documentation page http://msdn.microsoft.com/en-us/library/system.windows.frameworkelement.measureoverride.aspx for information about measuring child elements in a panel.

这篇关于在WPF中,如何在DataGrid之上显示AdornerLayer的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆