【问题标题】:How do Grid.Row and similar properties get such great DESIGN TIME support?Grid.Row 和类似属性如何获得如此出色的 DESIGN TIME 支持?
【发布时间】:2017-12-16 14:20:19
【问题描述】:

问题: Grid.Row、Grid.Column、Canvas.SetTop 等属性本身就具有很好的 DesignTime 支持。您将它们附加到子元素,并观察 xaml 更新。它们的实现与我下面的示例有何不同?

示例

在本例中,我创建了一个名为 position附加属性。我可以将 position 属性附加到网格中的任何子元素。这样做会更新他们的行和列。

public static void SetPosition(DependencyObject obj, Positioning value) => obj.SetValue(PositionProperty, value);
public static void GetPosition(DependencyObject obj) => (Positioning)obj.GetValue(PositionProperty);

public static readonly DependencyProperty PositionProperty = DependencyProperty.RegisterAttatched( "Position", typeof(Positioning),
    new PropertyMetadata( Positioning.Normal, OnPositionChanged));

public static void OnPositionChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
{
    UIElement item = obj as UIElement;
    if(item == null)
        return;

    switch((Positioning) e.NewValue)
    {
        case Positioning.Middle:
            Grid.SetRow(item, 4);
            Grid.SetColumn(item, 2); 
            break;
        default:
            Grid.SetRow(item, 0);
            Grid.SetColumn(item, 0);
    }
}

//Usage:
<Rectangle local:Position="Middle" Fill="Pink" Height="40" Width="40"/>

这适用于运行时,但不适用于设计时。我最好的猜测是可能在设计时没有调用 OnPositionChanged?

我尝试过的事情:

  • 当属性改变时调用函数(见上例)
  • 添加 FrameworkPropertyMetadataOptions.AffectsRender 等属性
  • 覆盖 ItemsControl 的 OnItemsChanged() 函数

【问题讨论】:

  • 我认为这是因为 Designer Code Base 方面支持此属性

标签: c# wpf datagrid design-time


【解决方案1】:

我不知道您将声明放在哪里,但以下方法有效:

窗口:

<Window
    x:Class="WpfApp1.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:local="clr-namespace:WpfApp1"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition />
            <RowDefinition />
            <RowDefinition />
        </Grid.RowDefinitions>
        <local:UserControl1 local:UserControl1.Position="Zero" Background="Red" />
    </Grid>
</Window>

控件:

using System.Windows;
using System.Windows.Controls;

namespace WpfApp1
{
    public partial class UserControl1
    {
        public static readonly DependencyProperty PositionProperty = DependencyProperty.RegisterAttached(
            "Position", typeof(Position), typeof(UserControl1),
            new PropertyMetadata(default(Position), PositionPropertyChangedCallback));

        public UserControl1()
        {
            InitializeComponent();
        }

        private static void PositionPropertyChangedCallback(DependencyObject o, DependencyPropertyChangedEventArgs e)
        {
            if (!(o is UIElement uiElement))
                return;

            var position = (Position) e.NewValue;
            var value = (int) position;
            Grid.SetRow(uiElement, value);
        }

        public static void SetPosition(DependencyObject element, Position value)
        {
            element.SetValue(PositionProperty, value);
        }

        public static Position GetPosition(DependencyObject element)
        {
            return (Position) element.GetValue(PositionProperty);
        }
    }

    public enum Position
    {
        Zero = 0,
        One = 1,
        Two = 2
    }
}

在这里,我可以看到设计时的变化 :)

示例 1:

示例 2:

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-12-15
    • 2014-06-25
    • 2018-09-17
    • 2016-11-15
    • 1970-01-01
    • 1970-01-01
    • 2012-01-05
    • 1970-01-01
    相关资源
    最近更新 更多