c# - How to wrap Datagrid columns in XAML -
i sorry don't know how explain better, want wrap columns in datagrid.
i not trying wrap text inside datagrid columns, actual columns of datagrid.
i have searched net , have looked through wpf 4.5 adam nathan , due lack of ability describe want , searches ever come text wrapping. , don't faintest idea how approach this.
this xaml have datagrid
<datagrid name="infocounttextblock" columnwidth="100" grid.row="3" grid.columnspan="4" margin="5" gridlinesvisibility="none" alternationcount="2"> <datagrid.rowstyle> <style targettype="datagridrow"> <setter property="background" value="white"/> <setter property="fontweight" value="normal"/> <style.triggers> <trigger property="alternationindex" value="1"> <setter property="background" value="#ddebf7"/> </trigger> <trigger property="ismouseover" value="true"> <setter property="background" value="#338fff"/> <setter property="foreground" value="white"/> </trigger> </style.triggers> </style> </datagrid.rowstyle> </datagrid>
and code behind,
foreach (string infooption in infooptions) { infocount.add( new infooption { info = infooption, instances = filteredselection.count(staff => staff.info_data == infooption) } ); } infocounttextblock.itemssource = infocount;
this illustrate trying achieve. right now.
and is out come trying achieve, hoping keep data in 1 datagrid connecting data database. arbitrarily, when data goes on 5 rows, moved to next block of columns , forth.
right. had time, achieved it. here steps:
firstly, i'm going define sample data type , sample data visualize things right inside designer, instead of having run every time. step not necessary since have data types defined. take care of 1 thing though. our control needs access property named rownumber
decide row/col of each element. should int
type property showing row index of element within collection.
public class fiverowdata { public int rownumber { get; set; } public string column1 { get; set; } public string column2 { get; set; } } public class fiverowlist : list<fiverowdata> { }
next, add sample xml data file (add new item > resource dictionary) project. not necessary , here design-time support. paste following sample data file:
<yourproject:fiverowlist xmlns:yourproject="clr-namespace:yourproject" capacity="37"> <yourproject:fiverowdata rownumber="1" column1="content 1" column2="item 1" /> <yourproject:fiverowdata rownumber="2" column1="content 2" column2="item 2" /> <yourproject:fiverowdata rownumber="3" column1="content 3" column2="item 3" /> <yourproject:fiverowdata rownumber="4" column1="content 4" column2="item 4" /> <yourproject:fiverowdata rownumber="5" column1="content 5" column2="item 5" /> <yourproject:fiverowdata rownumber="6" column1="content 6" column2="item 6" /> <yourproject:fiverowdata rownumber="7" column1="content 7" column2="item 7" /> <yourproject:fiverowdata rownumber="8" column1="content 8" column2="item 8" /> <yourproject:fiverowdata rownumber="9" column1="content 9" column2="item 9" /> <yourproject:fiverowdata rownumber="10" column1="content 10" column2="item 10" /> <yourproject:fiverowdata rownumber="11" column1="content 11" column2="item 11" /> <yourproject:fiverowdata rownumber="12" column1="content 12" column2="item 12" /> <yourproject:fiverowdata rownumber="13" column1="content 13" column2="item 13" /> <yourproject:fiverowdata rownumber="14" column1="content 14" column2="item 14" /> <yourproject:fiverowdata rownumber="15" column1="content 15" column2="item 15" /> <yourproject:fiverowdata rownumber="16" column1="content 16" column2="item 16" /> <yourproject:fiverowdata rownumber="17" column1="content 17" column2="item 17" /> </yourproject:fiverowlist>
now actual work. add new usercontrol
wpf project. name fiverowwrapper
(or whatever wish, take care of renaming things in following code). go xaml , replace existing code following:
<itemscontrol x:class="fiverowwrapper" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:local="clr-namespace:yourproject" xmlns:syswin="clr-namespace:system.windows;assembly=presentationframework" mc:ignorable="d" d:designheight="180" d:designwidth="600" d:datacontext="{d:designdata source=fiverowlistsampledata.xaml}" itemssource="{binding}"> <itemscontrol.resources> <local:itemscounttocolcountconverter x:key="itemscounttocolcountconverter" /> <local:fiverowtorownumberconverter x:key="fiverowtorownumberconverter" /> <local:fiverowtocolnumberconverter x:key="fiverowtocolnumberconverter" /> </itemscontrol.resources> <itemscontrol.itemtemplate> <datatemplate datatype="local:fiverowdata"> <stackpanel orientation="horizontal"> <textblock text="{binding column1}" margin="10" /> <textblock text="{binding column2}" margin="10" /> </stackpanel> </datatemplate> </itemscontrol.itemtemplate> <itemscontrol.itemspanel> <itemspaneltemplate> <grid local:gridhelpers.rowcount="5" local:gridhelpers.columncount="{binding count, converter={staticresource itemscounttocolcountconverter}}" /> </itemspaneltemplate> </itemscontrol.itemspanel> <itemscontrol.itemcontainerstyle> <style targettype="{x:type contentpresenter}"> <setter property="grid.row" value="{binding rownumber, converter={staticresource fiverowtorownumberconverter}}" /> <setter property="grid.column" value="{binding rownumber, converter={staticresource fiverowtocolnumberconverter}}" /> </style> </itemscontrol.itemcontainerstyle> </itemscontrol>
a few points elaborate. using custom itemscontrol
uses grid
panel. serve overall container of our individual items. items in turn use itemtemplate
defined above containing stackpanel
2 textblock
s show properties of each item. sample class, have used column1
, column2
properties, can use properties or customize appearance of individual items in way want defining own itemtemplate
here. itemcontainerstyle
property @ bottom responsible binding grid.row
, grid.column
properties of each individual item , placing item appropriate cell within main grid
.
there 2 other things in xaml code above need explanation. firstly, need decide number of columns in our grid
, can computed dividing number of items 5. problem due grid
's design, cannot bind number of columns property , need handle indirectly through attached properties.
add new class project , name gridhelpers
(thanks rachel's helpful answer). replace contents of file following:
public class gridhelpers { public static readonly dependencyproperty columncountproperty = dependencyproperty.registerattached("columncount", typeof(int), typeof(gridhelpers), new propertymetadata(-1, columncountchanged)); public static int getcolumncount(dependencyobject obj) { return obj.getvalue(columncountproperty); } public static void setcolumncount(dependencyobject obj, int value) { obj.setvalue(columncountproperty, value); } public static void columncountchanged(dependencyobject obj, dependencypropertychangedeventargs e) { if (!(obj grid) || (int)e.newvalue < 0) return; grid grid = (grid)obj; grid.columndefinitions.clear(); (int = 0; <= (int)e.newvalue - 1; i++) { grid.columndefinitions.add(new columndefinition { width = gridlength.auto }); } } }
as see, class adds attached property grid
using can define number of columns dynamically. i'm using gridlength.auto
here, in case want equal-sized columns, can use fixed-size columns too.
lastly need following 3 converters:
- number of elements number of columns (divide number of elements 5, take ceiling)
- rownumber row (modulo 5)
- rownumber column (divide 5, take floor)
here's code 3 converters. define them anywhere in project:
public class itemscounttocolcountconverter : ivalueconverter { public object convert(object value, type targettype, object parameter, cultureinfo culture) { return (int)math.ceiling((int)value / 5f); } public object convertback(object value, type targettype, object parameter, cultureinfo culture) { throw new notimplementedexception(); } } public class fiverowtorownumberconverter : ivalueconverter { public object convert(object value, type targettype, object parameter, cultureinfo culture) { return ((int)value - 1) % 5f; } public object convertback(object value, type targettype, object parameter, cultureinfo culture) { throw new notimplementedexception(); } } public class fiverowtocolnumberconverter : ivalueconverter { public object convert(object value, type targettype, object parameter, cultureinfo culture) { return (int)math.floor(((int)value - 1) / 5f); } public object convertback(object value, type targettype, object parameter, cultureinfo culture) { throw new notimplementedexception(); } }
the final output of above effort looks in wpf designer:
lastly, control expand horizontally add more items collection. should place control inside scrollviewer
handle situation.
i leave background coloring , other smaller activities exercise you.
Comments
Post a Comment