WPF GridViewDataColumn Header - Workaround for string format

1 Answer 195 Views
GridView
alex
Top achievements
Rank 2
Bronze
Iron
Iron
alex asked on 16 Aug 2023, 04:42 PM | edited on 16 Aug 2023, 05:23 PM

Hello,

I followed your solution on this link to apply a string format on the Header of the column in the RadGridView:

https://www.telerik.com/forums/stringformat-not-working-for-gridviewdatacolumn-header

With this solution, if the bound property has a value "test", in the TextBlock.Text inside the header I will show "test 123" ("123" came from the StringFormat).

This solution works but I face a bug when I use it with another functionality. I have implemented a button that on click opens a ListBox on a ContextMenu to show/hide the RadGridViewColumns). See the following link:

https://www.telerik.com/forums/add-button-to-radgridview-column-header

The RadGridView.Columns are bound to the ListBox.

The ListBoxItem.Template has a Checkbox where the IsChecked property is bound to the Column visibility state and the Content property is bound to the Column header. 

If the Listbox is shown (by click on a button, the ListBox is displayed on a ContextMenu), the Header template is dissapeared from the GridViewDataColumn.Header and it is shown on the ListBoxItem. It likes the template is "moved".

If I put the DataTemplate on a resource with x:Shared=False then it still dissapears from the header and it appears twice on the ListBoxItem.

Note:

1. I tried to use the Header without a DataTemplate but I can't use a converter to append the "123" because I already have one converter that can't have other functionality.

2. My current workaround is to do the converter code and the text append on the code behind of the xaml. Then I can bind the xaml.cs String property to the GridViewDataColumn.Header and remove the DataTemplate. The problem with this solution is that I need to do this on each xaml, and cannot be set on a style. In addition, I don't want to use code behind at all.

3. Any workaround without using the DataTemplate will work for me. I can "live" with that problem if you help me solving this specific case because I usually don't use DataTemplates on headers at all.

4. If you can look at your code, I would appreciate if you can think how the DataTemplate is dissapeared. I think that you have a bug somewhere because a Binding should not remove a Template from your control.

The bug is the same as described in this post (screenshot attached)

https://www.telerik.com/forums/gridview-columns-headers-disappearing-after-binding-to-controlpanel

I need a workaround to display the complete text without DataTemplate, because the solution here of adding DataTemplate for all columns of the application is not aceptable. Maybe there is a way to trigger the Context on the ListBoxItem and changed the binding according to the content type?

Thank you,

Alex.

1 Answer, 1 is accepted

Sort by
0
Martin Ivanov
Telerik team
answered on 21 Aug 2023, 09:02 AM

Hello Alex,

The described behavior is expected. This happens because the same visual element (the value of the column's Header) is bound to two parent elements (the list item and the column header). This is not allowed in WPF. The same visual cannot have more than one parent visual. This is why the WPF binding system is moving the element to the last binding that tries to get it. In your case this is the list item. 

To avoid this behavior you can use DataTemplate for the header. In the header, you can bind the corresponding value, and then customize its appearance in the template.

The alternative solution is to manually re-assign the visual from the list item back to the Header of the column, when the context menu gets closed. But this approach is considered more of a hack, so I would recommend you to stick to the HeaderTemplate idea. 

Also, there are additional approaches that you can consider, like using an IValueConvert with the Header (instead of the DataTemplate approach), or using a separate property that contains the full header, which should omit the need to use the StringFormat.

I have prepared a small sample that shows the idea with the custom converter as it sounds suitable for your case, where you prefer to avoid the use of DataTemplates. I hope that helps.

Regards,
Martin Ivanov
Progress Telerik

Love the Telerik and Kendo UI products and believe more people should try them? Invite a fellow developer to become a Progress customer and each of you can get a $50 Amazon gift voucher.

alex
Top achievements
Rank 2
Bronze
Iron
Iron
commented on 26 Aug 2023, 08:02 AM

Thank you Martin for your detailed response.

I cannot use a converter because I have already a converter that performs specific logic and I can't add the string format to it.

Currently, I did the logic of the converter + string format in the xaml.cs and bound the Header property to a stirng property in the code behind. 

This is not a final solution since I don't use code behind at all and other developers on my team should remember that DataTemplate is not allowed for this feature.

I expect for the same behavior as other UIElement binding...

I cannot re-assign back the DataTemplate because the columns and menu are visible at the same time.

Can you add the StringFormat capability to the header?

Or expose another property that is updated when the DataTemplate changed. You can try get the text from the data template and assign to that property.

Martin Ivanov
Telerik team
commented on 28 Aug 2023, 09:33 AM

I have logged a new feature request to introduce a HeaderStringFormat property for the column. This is similar to the ContentStringFormat of ContentControl. The following blog explains (in a bit different context) why the StringFormat doesn't work in the binding of the columns' Header property.

One alternative solution that you can consider is to use a TextBlock in the Header. And then, in the control panel, instead of binding to the Header of the column, you can bind to the Text of the TextBlock. To do this, you can do something like this:

<CheckBox Content="{Binding Header.Text}" />

I have updated my last project to show this idea. I hope it helps.

alex
Top achievements
Rank 2
Bronze
Iron
Iron
commented on 29 Aug 2023, 04:37 PM

Thank you Martin,

I will wait for the implementation. It will be nice to receive an email if implemented.

As mentioned before, I can set the binding because I have a ListBox where only few columns (2 out of 20) have a DataTemplate, so changing the binding will cause a problem on normal columns.

Martin Ivanov
Telerik team
commented on 29 Aug 2023, 04:53 PM

If you click the "Follow"  button of the feature request in the portal, you will get notified by email, once is status changes.
Tags
GridView
Asked by
alex
Top achievements
Rank 2
Bronze
Iron
Iron
Answers by
Martin Ivanov
Telerik team
Share this question
or