【问题标题】:WPF Binding Without XAML没有 XAML 的 WPF 绑定
【发布时间】:2018-12-11 20:04:08
【问题描述】:

我有一个带有“网格窗口”的 WPF 应用程序。此窗口没有添加 XAML。我创建了一个网格(列和行),然后在每个 C# 中放置一个矩形。 这使我可以在设置“笔画”的位置创建一个网格,并在设置“填充”时在网格上显示位置。

整个网格设置相同,也就是说,如果网格的一部分是红色的,那么整个网格都是红色的。目前,我通过遍历所有矩形并设置“Stroke”属性来设置网格。这工作正常,但与大多数其他操作相比似乎非常慢。我想将 stroke 属性绑定到 C# 中的一个变量(除非迭代是一种合理的处理方式)。

我在这里查看了很多问题,但大多数都想使用 XAML。我下面的代码基于Binding without XAML [WPF]。没有错误,网格永远不会出现。

    // put a rectangle in each square
    for (int i = 0; i < x; i++) // for each column
    {
        for (int j = 0; j < y; j++) // for each row
        {
            // create a new rectangle with name, height, width, and starting color (transparent)
            var rect = new Rectangle()
            {
                Name = $"rec{(i + 1).ToString("00")}{(j + 1).ToString("00")}", //column 5 row 2 -> rec0502
                Height = squareSize,
                Width = squareSize,
                Fill = _ColorOff
            };

            // create the binding
            var binder = new Binding
            {
                Source = _GridColor, // Brush that is updated on color change
                Path = new PropertyPath("Stroke")
            };

            // apply the binding to the rectangle
            rect.SetBinding(Rectangle.StrokeProperty, binder);
            rect.DataContext = binder;

            // place the rectangle
            Grid.SetColumn(rect, i);         // current column
            Grid.SetRow(rect, (y - j - 1));  // same row but from the bottom (puts point 0,0 at bottom left)

            // add the rectangle to the grid
            grdBattleGrid.Children.Add(rect);
        }
    }

即使迭代没问题,我仍然想知道我做错了什么。

编辑:颜色名称是从单独窗口上的 ComboBox 中选择的。这会更新用户设置,进而引发我的“网格窗口”订阅的事件。在遍历矩形之前,我将名称转换为 SolidColorBrush。

【问题讨论】:

  • 为了创建一个更新其目标属性的绑定,您需要一个带有属性更改通知的源属性。我猜_GridColor 不是。也许添加一个带有更改通知的GridStroke 属性(例如实现 INotifyPropertyChanged)到包含您正在显示的代码的类。然后将 Binding 写为var binding = new Binding { Source = this, Path = new PropertyPath("GridStroke") };。不需要设置 Rectangle 的 DataContext。
  • 填充和网格颜色(通常)是不同的颜色。如果我将它绑定到 Color 属性,它将是相同的颜色,对吗?

标签: c# wpf data-binding wpf-controls


【解决方案1】:

最简单的解决方案是根本没有任何绑定。将_GridColor 分配给矩形的描边。每当(假定的 SolidColorBrush)_GridColor 的 Color 属性发生变化时,它都会影响所有 Rectangle。

public SolidColorBrush _GridColor { get; } = new SolidColorBrush(); 
...

var rect = new Rectangle
{
    Name = $"rec{(i + 1).ToString("00")}{(j + 1).ToString("00")}",
    Height = squareSize,
    Width = squareSize,
    Fill = _ColorOff,
    Stroke = _GridColor // here
};

Grid.SetColumn(rect, i);
Grid.SetRow(rect, (y - j - 1));
grdBattleGrid.Children.Add(rect);

通过为_GridColor 画笔的Color 属性分配一个值来更改矩形描边:

_GridColor.Color = Colors.Red;

【讨论】:

  • 如果我更新“_GridColor”,它会自动更新 Stroke 属性吗?
  • 当然。尝试例如_GridColor.Color = Colors.Red;
  • 在原始设置后更新_GridColor,对我来说不会改变笔画。当在组合框中选择新颜色名称时,我会更新 _GridColor。我可以看到调试器通过并更改 _GridColor,但 GUI 上没有更改。
  • 你还没有展示 _GridColor 实际上是什么,但假设它是一个 SolidColorBrush,初始化一次,然后只改变它的颜色,如我之前的评论所示。如果您想分配 new 画笔,请按照我在对该问题的第一条评论中解释的内容进行操作,即实施 INotifyPropertyChanged。
  • 这条评论很有帮助。我正在使用 Brush 并处理 SolidColorBrush。因此,“.Color”选项没有出现。我真的很感谢你在这方面的帮助。更新网格颜色的速度明显快于以前。
【解决方案2】:

您只需为Window 设置一次DataContext,而不是为每个Rectangle 设置一次。

Binding 是您自己的来自INotifyPropertyChanged 接口的视图模型类吗? Link to MS Docs

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-07-15
    • 2017-10-02
    • 2017-08-20
    • 2011-02-28
    • 2015-11-23
    • 2011-02-23
    • 2011-08-09
    • 2017-07-14
    相关资源
    最近更新 更多