There are several other posts that looked similar and I used their code to come close but I am still having problems.
Problem: I have a datatable with a number of columns which I have bound to the radgridview. This works. What I want to do now is restrict the columns based on additional data in the view model. The modelview contains the datatable and the columns which I would like to bind. I am somewhat new to WPF and MVVM. I used the example from this post http://www.telerik.com/forums/column-collections but again it didn't work as I expect.
Thank you for any suggestions or code.
4 Answers, 1 is accepted
Can you please share some more details on what are the restrictions you need to apply to the columns and what difficulties did you face using the example you referred?
I would also like to encourage you to open a new support ticket with a sample project illustrating your current implementation attached, as this would be the fastest way to guide you to a solution.
I am looking forward to your reply.
Best Regards,
Stefan
Telerik
Sure, I have a datatable with some number of columns. I am using the first column as the X on a graph, and each of the other columns represent a curve in the Y)
Each of the other columns mapped to controls which when selected SHOULD change the datagrid to display the first column and which ever other column is associated with that control. (The graph shows the other column in the Y on the graph) So when I select the control the view and viewmodel are set and bound, but during the binding I need to be able to only show the specified columns.
<
telerik:RadGridView
x:Name
=
"dataGrid"
ItemsSource
=
"{Binding Table.DefaultView}"
AutoGenerateColumns
=
"false"
AllowDrop
=
"True"
CanUserDeleteRows
=
"True"
AlternateRowBackground
=
"#FFCDCDCD"
CanUserInsertRows
=
"True"
SelectionMode
=
"Extended"
SelectionUnit
=
"Cell"
AlternationCount
=
"2"
ClipToBounds
=
"True"
AutoExpandGroups
=
"True"
ClipboardCopyMode
=
"All"
ClipboardPasteMode
=
"AllSelectedCells"
>
<
i:Interaction.Behaviors
>
<
local:ColumnBindingBehavior
Columns
=
"{Binding Columns}"
/>
</
i:Interaction.Behaviors
>
</
telerik:RadGridView.ContextMenu
>
ColumnBindingBehaviour is similar to a previous post
public
class
ColumnBindingBehavior : Behavior<RadGridView>
{
private
RadGridView Grid
{
get
{
return
AssociatedObject;
}
}
public
INotifyCollectionChanged Columns
{
get
{
return
(INotifyCollectionChanged)GetValue(ColumnsItemsProperty); }
set
{ SetValue(ColumnsItemsProperty, value); }
}
public
static
readonly
DependencyProperty ColumnsItemsProperty =
DependencyProperty.Register(
"Columns"
,
typeof
(INotifyCollectionChanged),
typeof
(ColumnBindingBehavior),
new
PropertyMetadata(OnColumnsPropertyChanged));
private
static
void
OnColumnsPropertyChanged(DependencyObject target, DependencyPropertyChangedEventArgs args)
{
var behavior = (ColumnBindingBehavior)target;
var collection = args.NewValue
as
INotifyCollectionChanged;
if
(collection !=
null
)
{
collection.CollectionChanged -= behavior.ContextColumns_CollectionChanged;
collection.CollectionChanged += behavior.ContextColumns_CollectionChanged;
}
}
protected
override
void
OnAttached()
{
base
.OnAttached();
Transfer(Columns
as
IList, Grid.Columns);
Grid.Columns.CollectionChanged -= GridColumns_CollectionChanged;
Grid.Columns.CollectionChanged += GridColumns_CollectionChanged;
}
void
ContextColumns_CollectionChanged(
object
sender, NotifyCollectionChangedEventArgs e)
{
UnsubscribeFromEvents();
Transfer(Columns
as
IList, Grid.Columns);
SubscribeToEvents();
}
void
GridColumns_CollectionChanged(
object
sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
UnsubscribeFromEvents();
Transfer(Grid.Columns, Columns
as
IList);
SubscribeToEvents();
}
private
void
SubscribeToEvents()
{
Grid.Columns.CollectionChanged += GridColumns_CollectionChanged;
if
(Columns !=
null
)
{
Columns.CollectionChanged += ContextColumns_CollectionChanged;
}
}
private
void
UnsubscribeFromEvents()
{
Grid.Columns.CollectionChanged -= GridColumns_CollectionChanged;
if
(Columns !=
null
)
{
Columns.CollectionChanged -= ContextColumns_CollectionChanged;
}
}
public
static
void
Transfer(IList source, IList target)
{
if
(source ==
null
|| target ==
null
)
return
;
target.Clear();
foreach
(var o
in
source)
{
target.Add(o);
}
}
}
If the autogeneratecolumns is on I get all of them, if off I get nothing.
There is something Im doing wrong but I don't know what.
So I figured it out. When I set the Datacontext for the control, the all the CollectionChanged delegates where called THEN the Columns changed property was called. The Columns value was then set but nothing else was changed. Notice I added the Transfer to the OnColumnsPropertyChanged and it all started to work.
public
class
ColumnBindingBehavior : Behavior<RadGridView>
{
private
RadGridView Grid
{
get
{
return
AssociatedObject;
}
}
public
INotifyCollectionChanged Columns
{
get
{
return
(INotifyCollectionChanged)GetValue(ColumnsItemsProperty); }
set
{ SetValue(ColumnsItemsProperty, value); }
}
public
static
readonly
DependencyProperty ColumnsItemsProperty =
DependencyProperty.Register(
"Columns"
,
typeof
(INotifyCollectionChanged),
typeof
(ColumnBindingBehavior),
new
PropertyMetadata(OnColumnsPropertyChanged));
private
static
void
OnColumnsPropertyChanged(DependencyObject target, DependencyPropertyChangedEventArgs args)
{
var behavior = (ColumnBindingBehavior)target;
var collection = args.NewValue
as
INotifyCollectionChanged;
if
(collection !=
null
)
{
// collection.CollectionChanged -= behavior.ContextColumns_CollectionChanged;
// behavior.Grid.Columns.CollectionChanged -= GridColumns_CollectionChanged;
Transfer(behavior.Columns
as
IList, behavior.Grid.Columns);
// collection.CollectionChanged += behavior.ContextColumns_CollectionChanged;
}
}
protected
override
void
OnAttached()
{
base
.OnAttached();
Transfer(Columns
as
IList, Grid.Columns);
//Grid.Columns.CollectionChanged -= GridColumns_CollectionChanged;
//Grid.Columns.CollectionChanged += GridColumns_CollectionChanged;
}
void
ContextColumns_CollectionChanged(
object
sender, NotifyCollectionChangedEventArgs e)
{
UnsubscribeFromEvents();
Transfer(Columns
as
IList, Grid.Columns);
SubscribeToEvents();
}
void
GridColumns_CollectionChanged(
object
sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
UnsubscribeFromEvents();
Transfer(Grid.Columns, Columns
as
IList);
SubscribeToEvents();
}
private
void
SubscribeToEvents()
{
//Grid.Columns.CollectionChanged += GridColumns_CollectionChanged;
//if (Columns != null)
//{
// Columns.CollectionChanged += ContextColumns_CollectionChanged;
//}
}
private
void
UnsubscribeFromEvents()
{
//Grid.Columns.CollectionChanged -= GridColumns_CollectionChanged;
//if (Columns != null)
//{
// Columns.CollectionChanged -= ContextColumns_CollectionChanged;
//}
}
public
static
void
Transfer(IList source, IList target)
{
if
(source ==
null
|| target ==
null
)
return
;
target.Clear();
foreach
(var o
in
source)
{
target.Add(o);
}
}
}
Hope someone else can use this.
I am glad that you have found a resolution for the issue you were experiencing. Thank you for sharing it with us.
Do not hesitate to contact us in case you have any other questions on our controls.
Best Regards,
Stefan
Telerik