[英]How to give a glass appearance to the control under an adorner?
當裝飾器放置在 Windows 10 用戶控件上時,我試圖“模糊”它。
更確切地說,我在 wpf 用戶窗口中有一個 datagrid 控件。 選擇DataGrid中的單元格時,在DataGrid控件上創建編輯ADORNER。
public DataGridAnnotationAdorner(DataGrid adornedDataGrid, IVisit visit, DateTime TableDate)
: base(adornedDataGrid)
{
Control = new DataGridAnnotationControl(visit, TableDate);
AddLogicalChild(Control);
AddVisualChild(Control);
Loaded += DataGridAnnotationAdorner_Loaded;
}
private void DataGridAnnotationAdorner_Loaded(object sender, RoutedEventArgs e)
{
EnableBlur(AdornedElement);
}
加載的事件然后調用(一個非常標准的)模糊/玻璃效果方法:
internal void EnableBlur(UIElement dataGrid)
{
HwndSource source = (HwndSource)PresentationSource.FromVisual(dataGrid);
IntPtr hwnd = source.Handle;
var accent = new AccentPolicy();
accent.AccentState = AccentState.ACCENT_ENABLE_BLURBEHIND;
var accentStructSize = Marshal.SizeOf(accent);
var accentPtr = Marshal.AllocHGlobal(accentStructSize);
Marshal.StructureToPtr(accent, accentPtr, false);
var data = new WindowCompositionAttributeData();
data.Attribute = WindowCompositionAttribute.WCA_ACCENT_POLICY;
data.SizeOfData = accentStructSize;
data.Data = accentPtr;
SetWindowCompositionAttribute(hwnd, ref data);
Marshal.FreeHGlobal(accentPtr);
}
沒有報告錯誤......但它不起作用。
那么,如何為裝飾器下的控件提供“玻璃”外觀?
TIA
我不確定我能不能給你一個完整的解決方案,但我至少可以解釋為什么你的嘗試不起作用,並可能為你指明正確的方向。
在 WinForms(我認為是 C++)中,每個控件都是它自己的“迷你窗口”。 我的意思是每個控件都由操作系統賦予其自己的“句柄”,操作系統將它們視為屏幕上的單個實體。 WPF 不同,窗口中“單獨控件”的錯覺是由 WPF 框架創建的。 就操作系統而言,只有一個實體: Window
和所有進一步的邏輯都由 WPF 在內部處理。 不過,這只是大多數情況下的真實情況,我稍后會提到。
我提出這一點的原因是因為您的代碼行PresentationSource.FromVisual(dataGrid)
將為您提供托管DataGrid
的Window
的句柄,而不是DataGrid
本身獨有的句柄(因為DataGrid
沒有手柄)。 因此,您使用該句柄執行的所有其他操作實際上都針對整個 WPF Window
。
WPF Window
內的所有渲染都由 WPF 框架(加上您的代碼)在內部處理,而不是由操作系統直接處理(如在 WinForms 和 C++ 中),因此使用本機方法告訴操作系統如何渲染某些內容將不起作用Window
內的特定元素。
在我看來,您可以采用兩種方法來嘗試創建這種效果:
您可以嘗試在 WPF 中重新創建“玻璃狀”效果。 這將涉及重新創建或獲取用於視覺扭曲區域以產生該效果的任何算法,然后以某種方式將其實現到控件中。 除了谷歌,我真的不知道從哪里開始。
你可以嘗試把那些有自己處理其他WPF元素的優勢。
我知道的兩個主要的 WPF 元素有自己的句柄是Window
和Popup
。 您也許可以創建其中一個並將其放置在您需要的位置,就像您目前對您的崇拜者所做的那樣。 不過這會變得很棘手,因為這些元素實際上在產生它們的Window
之外並且並沒有真正鏈接到它。 因此,當您在桌面上移動主Window
, Popup
Window
或子Window
不會隨之移動。 您也可以在 WPF 窗口和您創建的彈出窗口之間拖動其他窗口(不過不確定)。
在這個標題下可能還有另一種可能性,那就是WindowsFormsHost
控件。 這是在 WPF 窗口中承載 WinForms 控件的 WPF 控件。 托管在內部的 WinForms 控件可能由操作系統賦予它們自己的句柄(因為這就是 WinForms 的操作方式)。 這可能是您最好的選擇,除非我從未嘗試過,而且我不知道WindowsFormsHost
將如何與它周圍或下方的其他元素進行交互。 因此,它也可能根本無法滿足您的需求。
祝你好運。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.