Scenario: Displays some columns in the DataGrid based on the configuration file.
Problem: The Columns collection is just a property of the DataGrid, which is not visible in the logical tree or the visual tree, and does not inherit the DataContext property.
Through the online access to a variety of information, methods can be attributed to the following several, the following will be shown.
Method One: Attach DataContext property to DataGridColumn
The method needs to use a helper class (a global instance needs to be created), with the following details:
Public classDatagridcontexthelper {StaticDatagridcontexthelper () {DependencyProperty DP= FrameworkElement.DataContextProperty.AddOwner (typeof(DataGridColumn)); FrameworkElement.DataContextProperty.OverrideMetadata (typeof(DataGrid),NewFrameworkpropertymetadata (NULL, Frameworkpropertymetadataoptions.inherits,NewPropertychangedcallback (ondatacontextchanged)); } Public Static voidondatacontextchanged (DependencyObject D, DependencyPropertyChangedEventArgs e) {DataGrid grid = d asDataGrid; if(Grid! =NULL) { foreach(DataGridColumn Colinchgrid. Columns) {Col. SetValue (Frameworkelement.datacontextproperty, E.newvalue); } } } }
Sample foreground bindings
<datagridtextcolumn x:name="col2" header="testcolumn " Visibility="{Binding (frameworkelement.datacontext). Show,relativesource={relativesource self},converter={staticresource cc}}"></ Datagridtextcolumn>
Example of a background binding
var New Binding (); = Bindingmode.oneway; Binding. RelativeSource=new RelativeSource (relativesourcemode.self); New Booleantovisibilityconverter (); Binding. Path=new PropertyPath ("(Frameworkelement.datacontext). Show"); Bindingoperations.setbinding (obj, datagridcolumn.visibilityproperty, binding);
Method Two: Bind directly to the VM via source
Example code:
var New Binding (); = Bindingmode.oneway; = vm; New Booleantovisibilityconverter (); New PropertyPath ("Show"); Bindingoperations.setbinding (obj, datagridcolumn.visibilityproperty, binding);
Method Three: Bind with a proxy class for the VM through source
proxy class
Freezable can inherit DataContext even if they are not in the visual tree or the logical tree
Public classbindingproxy:freezable {#regionOverrides of Freezableprotected OverrideFreezable Createinstancecore () {return NewBindingproxy (); } #endregion Public ObjectData {Get{return(Object) GetValue (Dataproperty); } Set{SetValue (dataproperty, value);} } Public Static ReadOnlyDependencyProperty Dataproperty =Dependencyproperty.register ("Data",typeof(Object), typeof(Bindingproxy)); }
Foreground binding Code
<datagrid x:name="DG"Horizontalalignment=" Left"Verticalalignment="Top"height="253"Width="436"Itemssource="{Binding Persons}"AutoGenerateColumns="False"> <DataGrid.Resources><dgtest:bindingproxy x:key="proxy" data="{Binding} "/></DataGrid.Resources> <DataGrid.Columns> <datagridtextcolumn x:name="col1"Header="Testcolumn"binding="{Binding Name}"></DataGridTextColumn> <datagridtextcolumn x:name="col2"Header="Testcolumn"Visibility="{Binding (frameworkelement.datacontext). Show,relativesource={relativesource self},converter={staticresource cc}}"></DataGridTextColumn><datagridtextcolumn x:name="col3" header="testcolumn
"
Visibility=
"
{Binding Data.show,source={staticresource PR Oxy},converter={staticresource cc}}
"></DataGridTextColumn>
</DataGrid.Columns> </DataGrid>
Method Four: Through a proxy control to implement
A proxy control is similar to a proxy object because it can inherit the DataContext property, but one that is seen in the logical tree. Examples are as follows:
<frameworkelement x:name="dummyelement"visibility="collapsed"/> <DataGrid> <DataGrid.Columns> <datagridtextcolumn header="Test"Binding="{Binding Name}"Visibility="{Binding datacontext.isenable,Source={x:reference Dummyelement}}"/></DataGrid.Columns> </DataGrid>
Bindings for WPF DataGrid visibility