如何为自定义网格控件设置自定义背景依赖属性

发布于 2024-12-13 07:02:50 字数 3827 浏览 0 评论 0原文

我使用了网上找到的一个示例来创建自定义网格控件。它允许我放置我想要制作日历的网格线。但现在当我去设置背景时,它会阻止我的自定义网格线显示。

我知道这是因为 OnRender 首先被调用,然后背景正在摆脱我的自定义设置。我摆脱了 OnRender 上的覆盖,但仍然没有运气。所以我的问题是如何制作一个仍然允许显示网格线的自定义背景。

这是我想要的自定义控件的背景:如果我尝试将其添加到自定义控件中,我的网格线就会消失。

    <Grid.Background>
        <RadialGradientBrush>
            <GradientStop Color="#FFC3D6F5" Offset="0" />
            <GradientStop Color="#FFEFF5FF" Offset="1" />
        </RadialGradientBrush>
    </Grid.Background>

这是我在网上找到的自定义控件。它仅设置自定义网格线属性。我现在需要一个自定义背景属性。这有点困难,因为我的背景不是纯色的。

namespace Camp_
{    
public class GridControl : Grid
{

    #region Properties
    public bool ShowCustomGridLines
    {
        get { return (bool)GetValue(ShowCustomGridLinesProperty); }
        set { SetValue(ShowCustomGridLinesProperty, value); }
    }



    public static readonly DependencyProperty ShowCustomGridLinesProperty =
        DependencyProperty.Register("ShowCustomGridLines", typeof(bool), typeof(GridControl), new UIPropertyMetadata(false));

    public Brush GridLineBrush
    {
        get { return (Brush)GetValue(GridLineBrushProperty); }
        set { SetValue(GridLineBrushProperty, value); }
    }


    public static readonly DependencyProperty GridLineBrushProperty =
        DependencyProperty.Register("GridLineBrush", typeof(Brush), typeof(GridControl), new UIPropertyMetadata(Brushes.Black));



    public double GridLineThickness
    {
        get { return (double)GetValue(GridLineThicknessProperty); }
        set { SetValue(GridLineThicknessProperty, value); }
    }

    public static readonly DependencyProperty GridLineThicknessProperty =
        DependencyProperty.Register("GridLineThickness", typeof(double), typeof(GridControl), new UIPropertyMetadata(1.0));
    #endregion

    protected override void OnRender(DrawingContext dc)
    {  

        if (ShowCustomGridLines)
        {

            foreach (var rowDefinition in RowDefinitions)
            {
                dc.DrawLine(new Pen(GridLineBrush, GridLineThickness), new Point(0, rowDefinition.Offset), new Point(ActualWidth, rowDefinition.Offset));
            }

            foreach (var columnDefinition in ColumnDefinitions)
            {
                dc.DrawLine(new Pen(GridLineBrush, GridLineThickness), new Point(columnDefinition.Offset, 0), new Point(columnDefinition.Offset, ActualHeight));
            } 
            dc.DrawRectangle(Brushes.Transparent, new Pen(GridLineBrush, GridLineThickness), new Rect(0, 0, ActualWidth, ActualHeight));
        }
        base.OnRender(dc);
    }

    static GridControl()
    {
        DefaultStyleKeyProperty.OverrideMetadata(typeof(GridControl), new FrameworkPropertyMetadata(typeof(GridControl)));
    }
}
}

以及 XAML:

<customgridcontrol:GridControl ShowCustomGridLines="True" GridLineBrush="CornflowerBlue" ShowGridLines="False" >
                    <Grid.RowDefinitions>
                        <RowDefinition />
                        <RowDefinition />
                        <RowDefinition />
                        <RowDefinition />
                        <RowDefinition />
                        <RowDefinition />
                    </Grid.RowDefinitions>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition />
                        <ColumnDefinition />
                        <ColumnDefinition />
                        <ColumnDefinition />
                        <ColumnDefinition />
                        <ColumnDefinition />
                        <ColumnDefinition />
                    </Grid.ColumnDefinitions>
</customgridcontrol:GridControl>

I used an example I found online to create a custom grid control. It allows me to place the kind of gridlines that I want to make a calender. But now When I go to set the background it stops my custom gridlines from displaying.

I know it's b/c the OnRender is being called first and then the background which is getting rid of my custom settings. I tied getting rid of the override on OnRender but still no luck. So my question is how can I make a custom background that will still allow the gridlines to be shown.

This is the background I want on my custom control: If I try to add this to the custom control my gridlines disappear.

    <Grid.Background>
        <RadialGradientBrush>
            <GradientStop Color="#FFC3D6F5" Offset="0" />
            <GradientStop Color="#FFEFF5FF" Offset="1" />
        </RadialGradientBrush>
    </Grid.Background>

This is the custom control I found online. It only sets customgridline properties. I need a custom background property now. It's a little harder because my background is not a solid color.

namespace Camp_
{    
public class GridControl : Grid
{

    #region Properties
    public bool ShowCustomGridLines
    {
        get { return (bool)GetValue(ShowCustomGridLinesProperty); }
        set { SetValue(ShowCustomGridLinesProperty, value); }
    }



    public static readonly DependencyProperty ShowCustomGridLinesProperty =
        DependencyProperty.Register("ShowCustomGridLines", typeof(bool), typeof(GridControl), new UIPropertyMetadata(false));

    public Brush GridLineBrush
    {
        get { return (Brush)GetValue(GridLineBrushProperty); }
        set { SetValue(GridLineBrushProperty, value); }
    }


    public static readonly DependencyProperty GridLineBrushProperty =
        DependencyProperty.Register("GridLineBrush", typeof(Brush), typeof(GridControl), new UIPropertyMetadata(Brushes.Black));



    public double GridLineThickness
    {
        get { return (double)GetValue(GridLineThicknessProperty); }
        set { SetValue(GridLineThicknessProperty, value); }
    }

    public static readonly DependencyProperty GridLineThicknessProperty =
        DependencyProperty.Register("GridLineThickness", typeof(double), typeof(GridControl), new UIPropertyMetadata(1.0));
    #endregion

    protected override void OnRender(DrawingContext dc)
    {  

        if (ShowCustomGridLines)
        {

            foreach (var rowDefinition in RowDefinitions)
            {
                dc.DrawLine(new Pen(GridLineBrush, GridLineThickness), new Point(0, rowDefinition.Offset), new Point(ActualWidth, rowDefinition.Offset));
            }

            foreach (var columnDefinition in ColumnDefinitions)
            {
                dc.DrawLine(new Pen(GridLineBrush, GridLineThickness), new Point(columnDefinition.Offset, 0), new Point(columnDefinition.Offset, ActualHeight));
            } 
            dc.DrawRectangle(Brushes.Transparent, new Pen(GridLineBrush, GridLineThickness), new Rect(0, 0, ActualWidth, ActualHeight));
        }
        base.OnRender(dc);
    }

    static GridControl()
    {
        DefaultStyleKeyProperty.OverrideMetadata(typeof(GridControl), new FrameworkPropertyMetadata(typeof(GridControl)));
    }
}
}

And the XAML:

<customgridcontrol:GridControl ShowCustomGridLines="True" GridLineBrush="CornflowerBlue" ShowGridLines="False" >
                    <Grid.RowDefinitions>
                        <RowDefinition />
                        <RowDefinition />
                        <RowDefinition />
                        <RowDefinition />
                        <RowDefinition />
                        <RowDefinition />
                    </Grid.RowDefinitions>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition />
                        <ColumnDefinition />
                        <ColumnDefinition />
                        <ColumnDefinition />
                        <ColumnDefinition />
                        <ColumnDefinition />
                        <ColumnDefinition />
                    </Grid.ColumnDefinitions>
</customgridcontrol:GridControl>

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

余罪 2024-12-20 07:02:50

我认为你只需要在xaml代码中设置标准背景属性,如下所示:

<customgridcontrol:GridControl ShowCustomGridLines="True" GridLineBrush="CornflowerBlue" ShowGridLines="False" Background="Binding{ StaticResource BrushYouWantTo" >
                <Grid.RowDefinitions>
                    <RowDefinition />
                    <RowDefinition />
                    <RowDefinition />
                    <RowDefinition />
                    <RowDefinition />
                    <RowDefinition />
                </Grid.RowDefinitions>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition />
                    <ColumnDefinition />
                    <ColumnDefinition />
                    <ColumnDefinition />
                    <ColumnDefinition />
                    <ColumnDefinition />
                    <ColumnDefinition />
                </Grid.ColumnDefinitions>
</customgridcontrol:GridControl>

“你想要的画笔”必须在xaml代码中设置为资源,如下所示:

<Window.Resources>
   <RadialGradientBrush Name="BrushYouWantTo">
      <GradientStop Color="#FFC3D6F5" Offset="0" />
      <GradientStop Color="#FFEFF5FF" Offset="1" />
   </RadialGradientBrush>
</Window.Resources>

但是如果你想在程序运行时更改背景颜色您需要一个依赖属性和一个重新加载 GUI 的事件处理程序。要使用此事件处理程序,您必须使用 a 定义它

new UIPropertyMetadata(CustomGridBackgroundChanged)

并且事件处理程序定义可以如下所示:

  private static void CustomGridBackgroundChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
  {
     WindowName win = (WindowName)sender;
     if (win.PropertyChanged != null)
     {
        // at this place the gui will be reloaded
        win.PropertyChanged(win, new PropertyChangedEventArgs(null));
     }
  }

这只是一个想法,所以我真的不知道它在实践中是否有效...
但我希望它对你有一点帮助

I think you only have to set the standard background property in the xaml code like this:

<customgridcontrol:GridControl ShowCustomGridLines="True" GridLineBrush="CornflowerBlue" ShowGridLines="False" Background="Binding{ StaticResource BrushYouWantTo" >
                <Grid.RowDefinitions>
                    <RowDefinition />
                    <RowDefinition />
                    <RowDefinition />
                    <RowDefinition />
                    <RowDefinition />
                    <RowDefinition />
                </Grid.RowDefinitions>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition />
                    <ColumnDefinition />
                    <ColumnDefinition />
                    <ColumnDefinition />
                    <ColumnDefinition />
                    <ColumnDefinition />
                    <ColumnDefinition />
                </Grid.ColumnDefinitions>
</customgridcontrol:GridControl>

The "brush you want to" must set as resource in the xaml code like this:

<Window.Resources>
   <RadialGradientBrush Name="BrushYouWantTo">
      <GradientStop Color="#FFC3D6F5" Offset="0" />
      <GradientStop Color="#FFEFF5FF" Offset="1" />
   </RadialGradientBrush>
</Window.Resources>

But if you want to change the background color while the program is running you need a dependency property and a event handler who reload the gui. To use this event handler you must define it with a

new UIPropertyMetadata(CustomGridBackgroundChanged)

And the event handler definition can look like this:

  private static void CustomGridBackgroundChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
  {
     WindowName win = (WindowName)sender;
     if (win.PropertyChanged != null)
     {
        // at this place the gui will be reloaded
        win.PropertyChanged(win, new PropertyChangedEventArgs(null));
     }
  }

It is only an idea so i dont really know if it work in practice...
But i hope it help you a little bit

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文