В WPF, как отобразить AdornerLayer поверх DataGrid
Я использую WPF DataGrid из Codeplex. Я использую DatagridTemplateColumn, и я написал шаблоны данных для отображения содержимого в каждом столбце.
Теперь мне нужно отобразить какое-то справочное сообщение для пользователя, когда фокусируется любой элемент управления в сетке данных. Для этого я подумал об использовании слоя adorner. Я использовал загруженное событие 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)
{
.....
}
}
Теперь проблема заключается в следующем. Я прилагаю скриншот того, как это выглядит в датагрид. Если сетка данных имеет более 4 строк, все в порядке. Ниже приведен скриншот
Если в сетке данных меньше номеров строк, этот рекламодатель попадает внутрь сетки данных и не виден пользователю. Снимок экрана ниже
Как мне получить этот слой над надстройкой DataGrid? Пожалуйста, помогите мне!!!
2 ответа
Просто возьми верх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);
Я снова посмотрел на ваш вопрос и думаю, что это то, что вам нужно.
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, но это должно сработать. Однако следует учитывать, что если ваша DataGrid находится внутри другого контейнера (например, панели, сетки и т. Д.), Вы все равно можете столкнуться с проблемой отсечения.
Проблема отсечения связана с тем, что когда контейнер проверяет макет своих дочерних элементов, он обычно не учитывает их украшатели. Для борьбы с этим вам, возможно, потребуется создать собственный элемент управления и переопределить метод MeasuerOverride(ограничение размера).
Пример:
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 для получения информации об измерении дочерних элементов на панели.