c# - How to fill up datagrid with empty rows -
i have datagrid bound observable collection.
i'd accomplish similar thing shown in this post datagrid there additional considerations:
the datagrid can resized user. filling info table fixed number of rows not work purposes. the scrolling behavior should work properly.basically i'm trying create error list window similar 1 within visual studio.
i'd appreciate guidelines.
this tricky one. thought create adorner responsible drawing different lines need. i'm not fond of creating unnecessary row objects.
here starting illustration (there still glitches , need tweaking, think it's start.)
xaml
<window x:class="wpfapplication11.mainwindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:sys="clr-namespace:system;assembly=mscorlib" xmlns:local="clr-namespace:wpfapplication11" title="mainwindow" height="350" width="525"> <local:mydatagrid headersvisibility="column"> <local:mydatagrid.columns> <datagridtextcolumn header="column 123" binding="{binding}" /> <datagridtextcolumn header="column 2" binding="{binding}" /> <datagridtextcolumn header="column 33333333333333333333333" binding="{binding}" /> </local:mydatagrid.columns> <sys:string>row</sys:string> <sys:string>row</sys:string> </local:mydatagrid> </window>
control code
public static class visual_extensionmethods { public static t finddescendant<t>(this visual @this, predicate<t> predicate = null) t : visual { homecoming @this.finddescendant(v => v t && (predicate == null || predicate((t)v))) t; } public static visual finddescendant(this visual @this, predicate<visual> predicate) { if (@this == null) homecoming null; var frameworkelement = @this frameworkelement; if (frameworkelement != null) { frameworkelement.applytemplate(); } visual kid = null; (int = 0, count = visualtreehelper.getchildrencount(@this); < count; i++) { kid = visualtreehelper.getchild(@this, i) visual; if (predicate(child)) homecoming child; kid = child.finddescendant(predicate); if (child != null) homecoming child; } homecoming child; } } public class gridadorner : adorner { public gridadorner(mydatagrid datagrid) : base(datagrid) { datagrid.layoutupdated += new eventhandler(datagrid_layoutupdated); } void datagrid_layoutupdated(object sender, eventargs e) { invalidatevisual(); } protected override void onrender(drawingcontext drawingcontext) { base.onrender(drawingcontext); var mydatagrid = adornedelement mydatagrid; if (mydatagrid == null) throw new invalidoperationexception(); // draw horizontal lines var lastrowbottomoffset = mydatagrid.lastrowbottomoffset; var remainingspace = mydatagrid.rendersize.height - lastrowbottomoffset; var placeholderrowheight = mydatagrid.placeholderrowheight; var linenumber = (int)(math.floor(remainingspace / placeholderrowheight)); (int = 1; <= linenumber; i++) { rect rectangle = new rect(new size(base.rendersize.width, 1)) { y = lastrowbottomoffset + (i * placeholderrowheight) }; drawingcontext.drawrectangle(brushes.black, null, rectangle); } // draw vertical lines var reorderedcolumns = mydatagrid.columns.orderby(c => c.displayindex); double verticallineoffset = - mydatagrid.scrollviewer.horizontaloffset; foreach (var column in reorderedcolumns) { verticallineoffset += column.actualwidth; rect rectangle = new rect(new size(1, math.max(0, remainingspace))) { x = verticallineoffset, y = lastrowbottomoffset }; drawingcontext.drawrectangle(brushes.black, null, rectangle); } } } public class mydatagrid : datagrid { public mydatagrid() { background = brushes.white; loaded += new routedeventhandler(mydatagrid_loaded); placeholderrowheight = 20.0d; // random value, can changed } protected override void onrender(drawingcontext drawingcontext) { base.onrender(drawingcontext); } private static void mydatagrid_loaded(object sender, routedeventargs e) { var datagrid = sender mydatagrid; if (datagrid == null) throw new invalidoperationexception(); // add together adorner responsible drawing grid lines var adornerlayer = adornerlayer.getadornerlayer(datagrid); if (adornerlayer != null) { adornerlayer.add(new gridadorner(datagrid)); } // find datagridrowspresenter , set alignment top retrieve lastly row vertical offset datagrid.datagridrowspresenter.verticalalignment = system.windows.verticalalignment.top; } public double placeholderrowheight { get; set; } public double lastrowbottomoffset { { homecoming datagridcolumnheaderspresenter.rendersize.height + datagridrowspresenter.rendersize.height; } } public datagridcolumnheaderspresenter datagridcolumnheaderspresenter { { if (datagridcolumnheaderspresenter == null) { datagridcolumnheaderspresenter = this.finddescendant<datagridcolumnheaderspresenter>(); if (datagridcolumnheaderspresenter == null) throw new invalidoperationexception(); } homecoming datagridcolumnheaderspresenter; } } public datagridrowspresenter datagridrowspresenter { { if (datagridrowspresenter == null) { datagridrowspresenter = this.finddescendant<datagridrowspresenter>(); if (datagridrowspresenter == null) throw new invalidoperationexception(); } homecoming datagridrowspresenter; } } public scrollviewer scrollviewer { { if (scrollviewer == null) { scrollviewer = this.finddescendant<scrollviewer>(); if (scrollviewer == null) throw new invalidoperationexception(); } homecoming scrollviewer; } } private datagridrowspresenter datagridrowspresenter; private datagridcolumnheaderspresenter datagridcolumnheaderspresenter; private scrollviewer scrollviewer; }
this specific piece of code
void datagrid_layoutupdated(object sender, eventargs e) { invalidatevisual(); }
you don't want. it's easiest ugliest way onrender beingness called when has to. should forcefulness onrender called on column reordering , column size changed. luck !
c# .net wpf datagrid
No comments:
Post a Comment