gpt4 book ai didi

wpf - 如何淡出给定控件的所有内容 "around"?

转载 作者:行者123 更新时间:2023-12-03 01:00:56 24 4
gpt4 key购买 nike

在我的应用程序中,在某些情况下我需要一些模式行为,即只允许用户与 UI 的特定元素(例如组框中的所有控件)进行交互。我不想使用模式对话框,因此我尝试找到一种方法来“淡出”除应保持事件状态的控件之外的所有内容,最好是通过使其他所有内容变暗(从而为控件提供视觉焦点)有问题)。

如何实现这样的行为?请注意,应成为模态的元素始终是 UI 的一部分,因此我不能将其放在覆盖层或类似的东西上。

我偶然发现了装饰器和装饰器,但关于这些的信息相当少......

最佳答案

您可以将覆盖层应用到整个窗口,并设置该覆盖层的 OpacityMask ,使其在必须是模态的元素上方透明。我将尝试在几分钟内发布一个示例。

<小时/>

编辑:好的,这比我预期的要难一点......这是一个有点有效但丑陋的解决方案:

    private Grid _modalOverlay;

private void btnShowOverlay_Click(object sender, RoutedEventArgs e)
{
if (_modalOverlay != null)
root.Children.Remove(_modalOverlay);
_modalOverlay = MakeModalOverlay(groupBox1, root, 0.5);
root.Children.Add(_modalOverlay);
}

private static Grid MakeModalOverlay(FrameworkElement element, FrameworkElement root, double opacity)
{
var offset = GetRelativeOffset(element, root);

Grid g = new Grid();

var c0 = new ColumnDefinition();
c0.Width = new GridLength(offset.X);
var c1 = new ColumnDefinition();
c1.Width = new GridLength(element.ActualWidth);
var c2 = new ColumnDefinition();
c2.Width = new GridLength(root.ActualWidth - element.ActualWidth - offset.X);

var r0 = new RowDefinition();
r0.Height = new GridLength(offset.Y);
var r1 = new RowDefinition();
r1.Height = new GridLength(element.ActualHeight);
var r2 = new RowDefinition();
r2.Height = new GridLength(root.ActualHeight - element.ActualHeight - offset.Y);

g.ColumnDefinitions.Add(c0);
g.ColumnDefinitions.Add(c1);
g.ColumnDefinitions.Add(c2);
g.RowDefinitions.Add(r0);
g.RowDefinitions.Add(r1);
g.RowDefinitions.Add(r2);

Brush b = new SolidColorBrush(Colors.Black) { Opacity = opacity };
for (int i = 0; i < 3; i++)
for (int j = 0; j < 3; j++)
{
if (i == 1 && j == 1)
continue;

Rectangle r = new Rectangle();
r.Fill = b;
Grid.SetColumn(r, i);
Grid.SetRow(r, j);
g.Children.Add(r);
}

Panel.SetZIndex(g, int.MaxValue);

return g;
}

private static Vector GetRelativeOffset(Visual visual, Visual ancestor)
{
Visual tmp = visual;
Vector offset = default(Vector);
while (tmp != ancestor)
{
offset += VisualTreeHelper.GetOffset(tmp);

tmp = (Visual) VisualTreeHelper.GetParent(tmp);
if (tmp == null)
throw new ArgumentException("ancestor is not an visual ancestor of visual");
}
return offset;
}

private void btnHideOverlay_Click(object sender, RoutedEventArgs e)
{
if (_modalOverlay != null)
root.Children.Remove(_modalOverlay);
}

在上面的代码中,root 是窗口的根面板。

这个解决方案确实有效,但有两个主要问题:

  • 不支持调整大小;这可能可以通过使用转换器绑定(bind)覆盖网格的列宽和行高来解决,但这并不是很简单
  • 它会阻止您点击其他控件,但您仍然可以使用键盘与它们交互。我认为防止这种情况的唯一方法是实际禁用它们......

关于wpf - 如何淡出给定控件的所有内容 "around"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5861670/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com