RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 616293
Accepted
Александр Пузанов
Александр Пузанов
Asked:2020-01-18 18:35:07 +0000 UTC2020-01-18 18:35:07 +0000 UTC 2020-01-18 18:35:07 +0000 UTC

DataGridView + 第三方控件

  • 772

请告诉我,是否可以链接第三方控件DatagridView?特别是,RatingControl从DevExpress. 示例如下:

在此处输入图像描述

c#
  • 1 1 个回答
  • 10 Views

1 个回答

  • Voted
  1. Best Answer
    Denis Bubnov
    2020-06-08T17:52:23Z2020-06-08T17:52:23Z

    在 big SO的开放空间上,找到了与您的问题类似的答案,并且是一个相当不错的答案。问题听起来像这样:“Using a custom control in a DataGridView”(在DataGridView中使用自定义控件)。事实上,源链接:Using a custom control in a DataGridView and the answer translation of the answer into Russian:

    首先你需要计算显示单元格的总数,你需要一个列表List<YourControl>来保存所有必要的控件。这些控件应该有自己DataGridView喜欢的Parent。这些元素的数量必须等于显示的单元格数量。然后,在事件处理程序中,CellPainting您必须更新列表中所有控件的位置。在事件处理程序中,让我们CellPainting添加更新代码,因为每当更新单元格值和边框时,它CellPainting都会运行并更新控件Location。这个过程有点复杂,但它有效。您可以使用属性将每个控件绑定到每个单元格reference,例如作为Tag属性的元素。

    一种方法。您只需要创建一个DataGridViewCell可用作CellTemplate常规DataGridViewColumn. 下面有相当多的代码:

    public class DataGridViewRatingColumn : DataGridViewColumn {
        public DataGridViewRatingColumn() : base(new DataGridViewRatingCell()) {
            base.ReadOnly = true;
            RatedStarColor = Color.Green;
            GrayStarColor = Color.LightGray;
            StarScale = 1;            
        }
        bool readOnly;
        public new bool ReadOnly
        {
            get {
                return readOnly;
            }
            set {
                readOnly = value;                
            }
        }
        Color ratedStarColor;
        Color grayStarColor;
        float starScale;
        public Color RatedStarColor {
            get { return ratedStarColor; }
            set {
                if (ratedStarColor != value) {
                    ratedStarColor = value;
                    if (DataGridView != null) DataGridView.InvalidateColumn(Index);
                }
            }
        }
        public Color GrayStarColor
        {
            get { return grayStarColor; }
            set {
                if (grayStarColor != value){
                    grayStarColor = value;
                    if(DataGridView != null) DataGridView.InvalidateColumn(Index);
                }
            }
        }
        public float StarScale {
            get { return starScale; }
            set {
                if (starScale != value) {
                    starScale = value;
                    DataGridViewRatingCell.UpdateBrushes(value);
                    if (DataGridView != null) DataGridView.InvalidateColumn(Index);
                }
            }
        }
    }    
    public class DataGridViewRatingCell : DataGridViewTextBoxCell {
        static DataGridViewRatingCell() {
            //Init star            
            List<PointF> points = new List<PointF>();
            bool largeArc = true;
            R = 10;
            r = 4;
            center = new Point(R, R);
            for (float alpha = 90; alpha <= 414; alpha += 36)
            {
                int d = largeArc ? R : r;
                double radAlpha = alpha * Math.PI / 180;
                float x = (float)(d * Math.Cos(radAlpha));
                float y = (float)(d * Math.Sin(radAlpha));
                points.Add(new PointF(center.X + x, center.Y + y));
                largeArc = !largeArc;
            }
            star.AddPolygon(points.ToArray());
            star.Transform(new Matrix(1, 0, 0, -1, 0, center.Y * 2));             
            //Init stars
            UpdateBrushes(1);                   
        }
        public DataGridViewRatingCell() {
            ValueType = typeof(int);
            ratedStarColor = Color.Green;
            grayStarColor = Color.LightGray;
            starScale = 1;
            UseColumnStarColor = true;
            UseColumnStarScale = true;            
        }                
        public override object DefaultNewRowValue {
            get {
                return 0;
            }
        }
        internal static void UpdateBrushes(float scale) {
            int space = 2*R;
            for (int i = 0; i < 5; i++) {
                if (stars[i] != null) stars[i].Dispose();
                stars[i] = (GraphicsPath)star.Clone();
                stars[i].Transform(new Matrix(scale, 0, 0, scale, space * i * scale, 0));                
                brushes[i] = CreateBrush(new RectangleF(center.X - R + space * i * scale, center.Y - R, R * 2 * scale, R * 2 * scale));
            }
        }
        private static LinearGradientBrush CreateBrush(RectangleF bounds)
        {
            var brush = new LinearGradientBrush(bounds,Color.White, Color.Yellow, LinearGradientMode.ForwardDiagonal);
            ColorBlend cb = new ColorBlend();
            Color c = Color.Green;
            Color lightColor = Color.White;
            cb.Colors = new Color[] { c, c, lightColor, c, c };
            cb.Positions = new float[] { 0, 0.4f, 0.5f, 0.6f, 1 };
            brush.InterpolationColors = cb;            
            return brush;
        }
        private void AdjustBrushColors(LinearGradientBrush brush, Color baseColor, Color lightColor)
        {
            //Note how we adjust the colors, using brush.InterpolationColors directly won't work.
            ColorBlend cb = brush.InterpolationColors;
            cb.Colors = new Color[] { baseColor, baseColor, lightColor, baseColor, baseColor };
            brush.InterpolationColors = cb;
        }        
        static GraphicsPath star = new GraphicsPath();
        static GraphicsPath[] stars = new GraphicsPath[5];
        static LinearGradientBrush[] brushes = new LinearGradientBrush[5];
        static Point center;
        static int R, r;
        int currentValue = -1;
        bool mouseOver;
        protected override void Paint(Graphics graphics, Rectangle clipBounds, Rectangle cellBounds, 
            int rowIndex, DataGridViewElementStates elementState, object value, object formattedValue, 
            string errorText, DataGridViewCellStyle cellStyle, DataGridViewAdvancedBorderStyle advancedBorderStyle, DataGridViewPaintParts paintParts)
        {
            base.Paint(graphics, clipBounds, cellBounds, rowIndex, elementState, value, formattedValue,
                errorText, cellStyle, advancedBorderStyle, paintParts & ~DataGridViewPaintParts.SelectionBackground & ~DataGridViewPaintParts.ContentForeground);             
            if (rowIndex == RowIndex && (paintParts & DataGridViewPaintParts.ContentForeground) != 0) {
                graphics.SmoothingMode = SmoothingMode.AntiAlias;
                if(Value != null) Value = Math.Min(Math.Max(0, (int)Value), 5);
                if (!mouseOver) currentValue = (int)(Value ?? 0);  
                PaintStars(graphics, cellBounds, 0, currentValue, true);
                PaintStars(graphics, cellBounds, currentValue, 5 - currentValue, false);
                graphics.SmoothingMode = SmoothingMode.Default;             
            }
        }
        protected override void OnMouseMove(DataGridViewCellMouseEventArgs e) {
            base.OnMouseMove(e);
            if (!mouseOver) mouseOver = true;
            if (IsReadOnly()) return;
            var lastStar = stars.Select((x, i) => new { x, i })
                                .LastOrDefault(x => x.x.IsVisible(e.Location));
            if (lastStar != null) {
                currentValue = lastStar.i + 1;                
                DataGridView.Cursor = Cursors.Hand;
            }
            else if(RowIndex > -1) {
                currentValue = (int)(Value ?? 0);
                DataGridView.Cursor = Cursors.Default;
            }
            DataGridView.InvalidateCell(this);
        }        
        protected override void OnClick(DataGridViewCellEventArgs e) {
            base.OnClick(e);
            if (IsReadOnly()) return;
            Value = currentValue == 1 && (int?) Value == 1 ? 0 : currentValue;
        }
        protected override void OnMouseLeave(int rowIndex) {
            base.OnMouseLeave(rowIndex);
            mouseOver = false;
            if (IsReadOnly()) return;
            if (rowIndex == RowIndex) {
                currentValue = (int)(Value ?? 0);
                DataGridView.InvalidateCell(this);
            }            
        }        
        private bool IsReadOnly() {
            var col = OwningColumn as DataGridViewRatingColumn;
            return col != null ? col.ReadOnly : false;
        }
        private void PaintStars(Graphics g, Rectangle bounds, int startIndex, int count, bool rated) {
            GraphicsState gs = g.Save();
           g.TranslateTransform(bounds.Left, bounds.Top);           
            var col = OwningColumn as DataGridViewRatingColumn;
            Color ratedColor = col == null ? Color.Yellow :
                UseColumnStarColor ? col.RatedStarColor : RatedStarColor;
            Color grayColor = col == null ? Color.LightGray :
                UseColumnStarColor ? col.GrayStarColor : GrayStarColor;
            float starScale = col == null ? 1 :
                UseColumnStarScale ? col.StarScale : StarScale;
            UpdateBrushes(starScale);
           for(int i = startIndex; i < startIndex + count; i++) {
               AdjustBrushColors(brushes[i], rated ? ratedColor : grayColor, rated ? Color.White : grayColor);
               g.FillPath(brushes[i], stars[i]);
               //g.DrawPath(Pens.Green, stars[i]);
           }
           g.Restore(gs);
        }        
        Color ratedStarColor;
        Color grayStarColor;
        float starScale;
        public Color RatedStarColor {
            get { return ratedStarColor; }
            set {
                if (ratedStarColor != value) {
                    ratedStarColor = value;
                    var col = OwningColumn as DataGridViewRatingColumn;
                    if (col != null && col.RatedStarColor != value) {
                        UseColumnStarColor = false;
                        DataGridView.InvalidateCell(this);
                    }
                }
            }
        }
        public Color GrayStarColor {
            get { return grayStarColor; }
            set {
                if (grayStarColor != value) {
                    grayStarColor = value;
                    var col = OwningColumn as DataGridViewRatingColumn;
                    if (col != null && col.GrayStarColor != value) {
                        UseColumnStarColor = false;
                        DataGridView.InvalidateCell(this);
                    }
                }
            }
        }
        //Change the star size via scaling factor (default by 1)
        public float StarScale {
            get { return starScale; }
            set {
                if (starScale != value) {
                    starScale = value;
                    var col = OwningColumn as DataGridViewRatingColumn;
                    if (col != null && col.StarScale != value) {
                        UseColumnStarScale = false;                        
                        DataGridView.InvalidateCell(this);                        
                    }
                }
            }
        }
        public bool UseColumnStarColor { get; set; }
        public bool UseColumnStarScale { get; set; }
    }
    

    注意:两个类DataGridViewRatingColumn必须DataGridViewRatingCell放在同一个文件中,因为里面有一个静态方法声明UpdateBrushes在DataGridViewRatingCell类中使用DataGridViewRatingColumn。如果您想将它们放在单独的文件中,您可以更改访问修饰符。查看提供的类、属性和方法 - 它们的名称不言而喻。它们可用于自定义控件(星号)的外观。显示用法的代码示例:

    dataGridView1.Columns.Add(new DataGridViewRatingColumn(){
         // свойства DataGridViewRatingColumn можно инициализировать здесь...
    });
    
    // Чтобы изменить ReadOnly, которое позволяет пользователю писать или нет, вам нужно
    // сначала преобразовать столбец в DataGridViewRatingColumn, это поведение вызвано 
    // ненормальным поведением переопределения ReadOnly (поэтому пришлось использовать новый).
    ((DataGridViewRatingColumn)dataGridView1.Columns[0]).ReadOnly = true; (default by false)
    
    // также вы должны включить DoubleBuffered в DataGridView для устранения мерцания
    typeof(Control).GetProperty("DoubleBuffered", 
        System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic)
      .SetValue(dataGridView1, true, null);
    

    可能翻译的不够完善,提前致歉。最主要的是答案的本质是明确的,并且对所有内容都进行了详细说明。代码中的小注释没有翻译。

    • 8

相关问题

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    Python 3.6 - 安装 MySQL (Windows)

    • 1 个回答
  • Marko Smith

    C++ 编写程序“计算单个岛屿”。填充一个二维数组 12x12 0 和 1

    • 2 个回答
  • Marko Smith

    返回指针的函数

    • 1 个回答
  • Marko Smith

    我使用 django 管理面板添加图像,但它没有显示

    • 1 个回答
  • Marko Smith

    这些条目是什么意思,它们的完整等效项是什么样的

    • 2 个回答
  • Marko Smith

    浏览器仍然缓存文件数据

    • 1 个回答
  • Marko Smith

    在 Excel VBA 中激活工作表的问题

    • 3 个回答
  • Marko Smith

    为什么内置类型中包含复数而小数不包含?

    • 2 个回答
  • Marko Smith

    获得唯一途径

    • 3 个回答
  • Marko Smith

    告诉我一个像幻灯片一样创建滚动的库

    • 1 个回答
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Алексей Шиманский 如何以及通过什么方式来查找 Javascript 代码中的错误? 2020-08-03 00:21:37 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    user207618 Codegolf——组合选择算法的实现 2020-10-23 18:46:29 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5