59 Answers, 1 is accepted
You cannot bind column properties since Binding is supported only for FrameworkElement – grid columns are plain DependencyObjects.
Sincerely yours,
Vlad
the Telerik team
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items.
using System.Windows; |
namespace Helpers |
{ |
public class ColumnHiderBinder |
{ |
public static readonly DependencyProperty ColumnListProperty = |
DependencyProperty.RegisterAttached("ColumnList", typeof(string), |
typeof(string), new PropertyMetadata(OnColumnListChanged)); |
public static string GetColumnList(DependencyObject d) |
{ |
return (string)d.GetValue(ColumnListProperty); |
} |
public static void SetColumnList(DependencyObject d, string value) |
{ |
d.SetValue(ColumnListProperty, value); |
} |
private static void OnColumnListChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) |
{ |
if (!(d is RadGridView)) return; |
var obj = ((RadGridView) d); |
foreach (var item in ((string) e.NewValue).Split(new [] {','})) |
{ |
obj.Columns[item].IsVisible = false; |
} |
} |
} |
} |
And then in your XAML:
<RadGridView Helpers:ColumnHiderBinder.ColumnList="{Binding ColumnsToHide}" > |
I am currently trying out your WPF RadGrid control, and first of all I really have to say great job to you all. It's a really good product compared to all the others out there.
However, I couldn't help it to notice your statement about DataBinding on DependencyObjects and I really cannot figure it out. Could you please be so kind as to helping me out on this one.
First lets look at this post by Mr. Nikolay Atanasov. In it, Telerik proudly announces native Silverlight 4 support of it's controls. In the product list provided, there is your RadControls suit for SL4 (it's the last one with the red rectangle around it). The post is dated to March 18, 2010. Your own post, in which you say that there is no DataBinding on DependencyObjects is dated to March 16, 2010. I am guessing that 2 days is not such a long time to turn things around so dramatically. Having said that, I am guessing that you probably had native support for SL4 long before the announcement day on March 18 (please correct me if I'm wrong).
By now your statement has been that your RadControls have native support for SL4, and that DataBinding is not possible on DependencyObjects. To be honest I'm really confused here. A long time ago I've read this post by Mr. Shawn Wildermuth about some of the changes in SL4. As he says, DataBinding is actually now available on DependencyObjects. When I read your post Vlad, I sat down and opened Visual Studio. Started out a new project and as it turns out, in SL4 the Binding has really moved out to the DependencyObject contrary to SL3 in which it really was in the FrameworkElement.
My question would be as follows: How can you say your RadControls have native SL4 support, when you guys don't even know the difference between SL3 and SL4?
I am sure that Vladimir Enchev had Silverlight 3 in mind when he made that comment. Binding on DependecyObject is indeed supported in Silverlight 4.
Excuse us for the misunderstanding.
Kind regards,
Milan
the Telerik team
This thread is related to columns visibility - can you elaborate a bit more on your scenario? Generally messing with rows visibility is not recommended since the grid virtualization will use it and you may get problems with such approach. It will be better if you filter your items before binding the grid or use the grid filtering to hide some of them.
Regards,Vlad
the Telerik team
Why dont work databinding on GridViewDataColumn on IsVisible in Silverlight4.
<Controls:GridViewDataColumn DataMemberBinding="{Binding Rusky}" Header="Russian" IsReadOnly="True" IsVisible="{Binding ColumnRuskyVisible}"/>
You can easily use a Binding to the IsVisible property of the column. I am sending you a sample project illustrating that functionality. Following the scenario in the sample application, once you check the CheckBox in the bottom, the visibility of the second column will be changed.
I hope that helps.
Maya
the Telerik team
This is now supported by the Silverlight (4) framework itself (unlike Silverlight 3) - you can remove old hacks.
Regards,Vlad
the Telerik team
I finally figured out why column visibility does not work and how to simulate.
Dont know if it Telerik or SL4 bug.
Based on your attachment I change in MainPage.xaml two lines.
<telerik:GridViewDataColumn IsVisible="{Binding IsChecked, ElementName=CheckBox1}" ...
<CheckBox x:Name="CheckBox1" />
- Now I expected that after application start CheckBox is unchecked and column is invisible. But column is visible.
- When checking and unchecking I expect column is hiding and showing. But nothing happens unless I select column with mouse.
MainPage.xaml
<
UserControl
x:Class
=
"BindingToIsVisible.MainPage"
xmlns:telerik
=
"http://schemas.telerik.com/2008/xaml/presentation"
xmlns:my
=
"clr-namespace:BindingToIsVisible"
mc:Ignorable
=
"d"
d:DesignHeight
=
"700"
d:DesignWidth
=
"700"
>
<
UserControl.Resources
>
<
my:MyViewModel
x:Key
=
"MyViewModel"
/>
</
UserControl.Resources
>
<
Grid
x:Name
=
"LayoutRoot"
Background
=
"White"
DataContext
=
"{StaticResource MyViewModel}"
>
<
Grid.RowDefinitions
>
<
RowDefinition
Height
=
"*"
/>
<
RowDefinition
Height
=
"Auto"
/>
</
Grid.RowDefinitions
>
<
telerik:RadGridView
Grid.Row
=
"0"
Name
=
"clubsGrid"
ItemsSource
=
"{Binding Clubs}"
AutoGenerateColumns
=
"False"
Margin
=
"5"
>
<
telerik:RadGridView.Columns
>
<
telerik:GridViewDataColumn
DataMemberBinding
=
"{Binding Name}"
/>
<
telerik:GridViewDataColumn
DataMemberBinding
=
"{Binding Established}"
Header
=
"Est."
IsVisible
=
"{Binding IsChecked, ElementName=CheckBox1}"
DataFormatString
=
"{}{0:yyyy}"
/>
<
telerik:GridViewDataColumn
DataMemberBinding
=
"{Binding StadiumCapacity}"
Header
=
"Stadium"
DataFormatString
=
"{}{0:N0}"
/>
</
telerik:RadGridView.Columns
>
</
telerik:RadGridView
>
<
StackPanel
Grid.Row
=
"1"
Orientation
=
"Horizontal"
>
<
TextBox
Text
=
"Click here to hide the last column"
/>
<
CheckBox
x:Name
=
"CheckBox1"
/>
</
StackPanel
>
</
Grid
>
</
UserControl
>
Following up your scenario, you need to set the Binding as follows:
<
CheckBox
x:Name
=
"CheckBox1"
IsChecked
=
"{Binding Columns[2].IsVisible,
ElementName=clubsGrid, Mode=TwoWay}"
/>
Maya
the Telerik team
thank you for answer.
You solution works great. Except one case. When I need show/hide two columns.
<telerik:GridViewDataColumn Header="system column 1" IsVisible="{Binding IsChecked, ElementName=CheckBox1}" ...
<telerik:GridViewDataColumn Header="system column 2" IsVisible="{Binding IsChecked, ElementName=CheckBox1}" ...
<CheckBox x:Name="CheckBox1" Header="System columns visible"/>
Is this behaviour expected? Will you fix this bug or this is by design right behaviour.
Thank for answer.
Thanks,
-Jarred Froman
On examining your requirements, another - and probably the most appropriate solution for that case - came up. What needs to be done here is to set the "Source" Property on defining the Binding of the IsVisible Property of the column. Thus once you set your ViewModel as a Resource, you will be able to use it afterwards like follows:
<
UserControl.Resources
>
<
my:MyViewModel
x:Key
=
"MyViewModel"
/>
</
UserControl.Resources
>
<
telerik:RadGridView.Columns
>
<
telerik:GridViewDataColumn
DataMemberBinding
=
"{Binding Name}"
/>
<
telerik:GridViewDataColumn
DataMemberBinding
=
"{Binding Established}"
Header
=
"Est."
IsVisible
=
"{Binding IsColumnVisible, Source={StaticResource MyViewModel}}"
DataFormatString
=
"{}{0:yyyy}"
/>
<
telerik:GridViewDataColumn
DataMemberBinding
=
"{Binding StadiumCapacity}"
Header
=
"Stadium"
IsVisible
=
"{Binding IsColumnVisible, Source={StaticResource MyViewModel}}"
DataFormatString
=
"{}{0:N0}"
/>
</
telerik:RadGridView.Columns
>
<
CheckBox
x:Name
=
"CheckBox1"
IsChecked
=
"{Binding IsColumnVisible, Source={StaticResource MyViewModel}, Mode=TwoWay}"
/>
Where "IsColumnVisible" is a property defined in the ViewModel.
Thus both columns as well as the CheckBox are aware where exactly to find that property - the MyViewModel.
I am sending you a sample project illustrating the proposed solution.
Maya
the Telerik team
I already discover this solution. It is little strange that ElementName= no working, but it doesnt matter.
I add extra property on ViewModel even I never touch it from ViewModel code.
Maybe this is SilverLight 4 bug :-)
Thank you for superb support!
I am having the same exact problem as Jaroslav, where a binding on GridViewColumn.IsVisible is only triggered when a cell within that column is selected. I am currently using Q2 2010 (no service packs), and I need to know how to combat the problem. Has telerik been able to reproduce this issue? Has it been fixed in recent service packs?
Looking forward to your response,
Sam
The fact that the ElementName is not working as expected in this case is due to some limitations in the Framework. Is it not appropriate for you to use the approach with setting the Source property of the Binding ? Please, share more details about your requirements, so that I could provide you with a proper solution.
Maya
the Telerik team
Yet when i setup a binding on IsVisible, the property is not honored *until i click within a cell of that column*. At that point, the databinding starts behaving normally. This tells me two things:
1. my binding is bound to the correct viewmodel property, because after clicking in the cell, it works as expected.
2. this is not the elementname problem you speak of, because I am not using it here at all.
--Sam
Based on the previous post, I got the impression that you are experiencing the same issue as the others with setting the ElementName binding property. How exactly are you setting the binding to IsVisible Property of the column ? Do you change it by checking/ unchecking a CheckBox as mentioned here before ? Any relevant code-snippet would be helpful.
Maya
the Telerik team
If you change example solution you have provided, and change bindning in checkbox to
<
telerik:GridViewDataColumn
DataMemberBinding
=
"{Binding Established}"
Header
=
"Est."
IsVisible
=
"{Binding ElementName=LayoutRoot, Path=DataContext.IsColumnVisible}"
DataFormatString
=
"{}{0:yyyy}"
/>
Binding won't work, right now I have created resource just to be able to hide column
:(
Alexey
When binding "IsVisible" property in the following way:
<
telerik:GridViewDataColumn
Header
=
"Pecent"
DataMemberBinding
=
"{Binding PercentDouble}"
IsVisible
=
"{Binding Path=DataContext.ShowPercentageColumn, ElementName=LayoutRoot, Mode=OneWay}"
/>
It does not work unless the user has clicked in the Column once. After the user clicks on the column, it work nicely.
Has anybody found a solution to this problem?
Thanks
Bruce
IsVisible="{Binding Path=DataContext.ShowPercentageColumn, ElementName=LayoutRoot, Mode=TwoWay}"
This should fix the problem.
If you don't have any binding Mode Like :
IsVisible="{Binding Path=DataContext.ShowPercentageColumn, ElementName=LayoutRoot}"
then it will use the default binding mode for that property, I assume that IsVisible's default binding mode is OneWay, which is why it is not working for that scenario either.
If you want to programatically change the value of a bound value and have the UI update itself automatically (without any user interaction on the UI), then you need to make the Mode=TwoWay.
Hope this helps.
Using the ElementName binding is not as reliable as expected and unfortunately it does not always provide the desired result. One possible approach would be to define a Resource and use it as a StaticResource in the Binding as demonstrated above.
Another technique is to wrap the RadGridView in a custom UserControls that exposes a property responsible for the column's visibility. I am sending you a sample project illustrating the proposed solution.
Maya
the Telerik team
Basically I am binding to a viewmodel, on that viewmodel is a bool property which i bind to IsVisible property on the GridViewDataColumn.
This bool property can change, depending on what mode the grid is in, and hence columns should hide/show depending on this.
When the datagrid is first shown, the binding is not initiated and only gets initiated when I click in the column.
I know this because I can change the binding to an incorrect property and I get a binding error in debug output (only when i click in the column), if I don't click in the column, i get no binding error, which tells me that the binding is not getting initialized until you click in the column.
Is there any solution to this ?
I want columns to be hidden/shown on first entry, clicking in the column to fire bindings is just ..... well ....wrong.
Many thanks
Dave
I have also noticed that clicking the cells seems to "activate" the binding, and after that point the column shows or hides appropriately based on the value of the property.
This seems like a bug to me. We were using the Microsoft DataGrid which didn't allow binding the Visibility property, so I was hoping that when we made the change to use the RadGridView, we would no longer have to set it programmatically.
Thanks,
Geoff
Terry
Columns in RadGridView for Silverlight are plain dependency objects rather than visual elements. Altering the behavior of RadGridView so that such bindings become possible would inevitably introduce a lot of breaking changes and inconsistent behavior with previous versions making upgrades to newer versions a pain for lots of our customers. This is the reason we recommend the solutions / workarounds mentioned before.
Regards,
Pavel Pavlov
the Telerik team
private void RadGridView_Loaded(object sender, RoutedEventArgs e) { var gridView = (GridViewDataControl)sender; var originalCurrentColumn = gridView.CurrentColumn; foreach (var column in gridView.Columns) gridView.CurrentColumn = column; gridView.CurrentColumn = originalCurrentColumn; }
It does seem that Telerik could make this happen by default, if they haven't already fixed it in the latest version.
This seems like a MAJOR oversight in the control.
Are you referring to your post on March 17th? I don't see anything in that post regarding binding to IsVisible but if you are just saying that this could be done in combination with the code-behind, then I understand.
Tks.
Tks.
We had a similar problem the RadTreeListView (based on the RadGridView) when binding a column's GridViewDataColumn.IsVisible to a property in the ViewModel. A workaround was to create a subclass of the RadTreeListView, add a dependency property that in turn was bound to the ViewModel's property, and use the dependency property's property change callback to programmatically update the column's IsVisible property.
BTW, setting a column's IsVisible to False within the xaml to initially hide the column was not working correctly. So we had to remove this from the xaml and programmatically set the IsVisible value to false within an override of OnApplyTemplate in the treeview subclass.
Combining the two is working great for us.
public class CustomTreeListView : RadTreeListView
{
public CustomTreeListView() : base()
{
}
#region DTDColumnVisible Dependency Property
/// <
summary
>
/// Dependency property used for changing the DTDColumn visibility. Binding directly to GridViewDataColumn.IsVisible
/// property does not work. Workaround.
/// </
summary
>
public bool DTDColumnVisible
{
get { return (bool)this.GetValue(DTDColumnVisibleProperty); }
set { SetValue(DTDColumnVisibleProperty, value); }
}
public static readonly DependencyProperty DTDColumnVisibleProperty = DependencyProperty.Register(
"DTDColumnVisible", typeof(bool), typeof(CustomTreeListView), new PropertyMetadata(false, new PropertyChangedCallback(OnDTDColumnVisibleChanged)));
private static void OnDTDColumnVisibleChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
{
// Update the DTDColumn visibility
CustomTreeListView treelistview = obj as CustomTreeListView;
if (treelistview != null)
treelistview.Columns["DTDColumn"].IsVisible = (bool)args.NewValue;
}
#endregion DTDColumnVisible Dependency Property
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
this.Columns["DTDColumn"].IsVisible = false;
}
}
I have the latest controls and it doesn't seem to be picking up the bindings for IsVisibleProperty, IsReadOnlyProperty or HeaderProperty at all. I've tried hooking into the Loaded event like John suggested but it doesn't seem to make a difference. I'm using BindingOperations.SetBinding() to set the bindings on the GridViewDataColumn instance.
I've noticed that there is an IsReadOnlyBinding which I can work with but I still need to be able to bind the visibility and header to my viewmodel. If it's just not possible I'll probably do something the the MVVM Lite messaging framework.
In WPF it works as expected, so why shall it be a breaking change to fix this BUG?
edit: When I set IsVisible to False via ViewModel and click a cell within that column the column disappears and the program crashes...
KO
Could anybody help me to set binding for GridViewDataColumn.IsVisible property from code behind?
Thanks
Here's what worked for me. The xaml binding is ignored, so I set bindings in the Loaded event for the page the grid is in. In my view model (based on INotifyPropertyChanged, naturally), I have one boolean property for each column in the grid, and the names of these properties correspond to the UniqueName fields for each column, for example, IsCol1Visible, IsCol2Visible, etc.
In the loaded event I set the bindings like this:
Binding b;
foreach
(GridViewBoundColumnBase c
in
grid.Columns)
{
b =
new
Binding(
string
.Format(
"Is{0}Visible"
, c.UniqueName));
b.Mode = BindingMode.TwoWay;
b.Source = View;
BindingOperations.SetBinding(c, GridViewDataColumn.IsVisibleProperty, b);
}
I don't know if this is a good way, or if there is a better way, but this certainly works. Hope that helps!
Kelly
Thanks a lot! This code works like a charm!
Juliana
1.) Create a DataContextProxy class, as in :
http://forums.silverlight.net/post/539919.aspx
i have used this proxy class in SL4 and SL5 and it works pretty well when using mvvm.
2.) Add a resource to your user control:
<myns:DataContextProxy x:Key="DCProxy/>
3.) Bind the IsVisible property to a property of your view model:
<telerik:GridViewDataColumn
Width="120"
DataMemberBinding="{Binding MyAdress, Mode=TwoWay}"
IsVisible="{Binding DataSource.IsMyAddressVisible, Source={StaticResource DCProxy}}">
4.) Remeber to call PropertyChanged when IsMyAddressVisible changes its value in your view model.
Hope it helps,
Guillermo
IsVisible="{Binding Path=DataContext.IsColumnVisible, RelativeSource={RelativeSource FindAncestor, AncestorType=Border}}"
We are using the 2012.2.725.1050 build of SL controls. Is John's code behind workaround still the only way to get this to work. We require to bind this directly within the XAML without the need for code behind. Any update?
thx...vsdotnetguy
Hi Bob,Even we are using the same 2012.2.725.1050 build with SL5, and I am able to set the IsVisible property directly
from XAML and it works with no issues.
Telerik Team,
Binding from ViewModel to set IsVisible property of a GridVIewDataColumn doesn't work,
even the workarounds provided by many guys here to create a Static Resource doesn't work because,
we cannot create a parameterless constructor, without which I cannot access myViewModel class from XAML.
Can you guys provide us with a solution??
Thnx
Chethan
<
TextBox
Height
=
"23"
Name
=
"textBox1"
Width
=
"120"
Text
=
"test"
/>
<
telerik:RadGridView
x:Name
=
"dgrDetailsFacture"
ItemsSource
=
"{Binding ElementName=dgrFacture,Path=SelectedItem.GrpLigneFacture}"
IsSynchronizedWithCurrentItem
=
"true"
CanUserResizeColumns
=
"False"
>
<
telerik:RadGridView.Columns
>
<
telerik:GridViewDataColumn
TextAlignment
=
"Center"
IsReadOnly
=
"True"
DataMemberBinding
=
"{Binding CodeArti, Mode=OneWay}"
Header
=
"Article"
HeaderTextAlignment
=
"Center"
Width
=
"90"
UniqueName
=
"article"
/>
<
telerik:GridViewDataColumn
TextAlignment
=
"Left"
IsReadOnly
=
"True"
DataMemberBinding
=
"{Binding Mode=OneWay, ElementName=textBox1, Path=Text}"
Header
=
"TEST"
HeaderTextAlignment
=
"Center"
Width
=
"*"
/>
</
telerik:RadGridView.Columns
>
</
telerik:RadGridView
>
In my case I have the grid in a user control which exposes a dependency property that that view model can bind to. The workaround of John's with the loaded event did not work, but changing the binding to:
IsVisible="{Binding ShowShare, ElementName=root}"
where root is the name of the UserControl element in the XAML works.
I've tried all the suggested work arounds viable for MVVM and none have worked.
Looks like Telerik have just stopped responding to this thread (which is 4 years long) even though it appears to be a need for many developers (myself included).
So is Telerik's official response "too difficult to implement"?
Cheers, Rob.
A production application would never instantiate the VM that way -- just not flexible ... I would expect (at least ours) production applications to setup the DataContext in a New instance of the UserControl passing whatever parameters are needed.
I was able to setup a checkbox that binds to IsVisible on a column but again that's user interaction which is not MVVM where I need to setup the IsVisible on the columns based on some parameter/state.
So at this point we've hit a rather significant show stopper unless this is implemented. Being able to hide columns in a grid using MVVM is key for our requirements.
Does anyone have any suggestions of alternate vendors that might provide such functionality in their Grids?
Cheers, Rob.
A lot of code for something so so so very simple ... it's one of those 14 years ago it would take 3 seconds and one line of code to hide a column ... today it's add a helper class, 20-30 lines of code ... this is progress?? If it is, then the future of software development is going to be pretty bleak.
Cheers, Rob.
Hi, I wanna bind a GridViewDataColumn IsVisible property, is there any way I can get that, Please...
Vlad, please don't just answer no, just tell me exactly how to get this done.
Can you check out the attached project where the Position column's IsVisible property in the nested grid is bound to a property in the Model? Please give this a try and let me know if that works for you. If you need further assistance, may I ask you to provide some more information about your scenario and perhaps a sample project.
I am looking forward to hearing from you.
Regards,
Vladimir Stoyanov
Progress Telerik