Bjorn Inge
Top achievements
Rank 1
Bjorn Inge
asked on 15 Nov 2013, 09:37 AM
Hello Telerik,
I'm trying to specify a binding on a tile's displayindex through a style. For some reason i get an exception stating:
System.ArgumentNullException occurred
HResult=-2147467261
Message=Value cannot be null.
Parameter name: property
Source=PresentationFramework
ParamName=property
StackTrace:
at System.Windows.Setter.CheckValidProperty(DependencyProperty property)
InnerException:
This is my style for the tiles:
Am I doing something obviously wrong?
I'm trying to specify a binding on a tile's displayindex through a style. For some reason i get an exception stating:
System.ArgumentNullException occurred
HResult=-2147467261
Message=Value cannot be null.
Parameter name: property
Source=PresentationFramework
ParamName=property
StackTrace:
at System.Windows.Setter.CheckValidProperty(DependencyProperty property)
InnerException:
<!-- Tile Style --> <Style TargetType="{x:Type telerik:Tile}">
<Setter Property="Background">
<Setter.Value>
<LinearGradientBrush>
<GradientStop Color="{Binding RelativeSource={RelativeSource AncestorType={x:Type telerik:Tile}, Mode=FindAncestor}, Path=Content.Color.StartColor}" Offset="0.0" />
<GradientStop Color="{Binding RelativeSource={RelativeSource AncestorType={x:Type telerik:Tile}, Mode=FindAncestor}, Path=Content.Color.EndColor}" Offset="1.0" />
</LinearGradientBrush>
</Setter.Value>
</Setter>
<Setter Property="TileType" Value="{Binding RelativeSource={RelativeSource Mode=Self}, Path=Content.Size, Converter={StaticResource tileTypeConverter}}" />
<Setter Property="DisplayIndex" Value="{Binding RelativeSource={RelativeSource AncestorType={x:Type telerik:Tile}, Mode=FindAncestor}, Path=Content.DisplayIndex, Mode=OneTime}" />
</Style>Am I doing something obviously wrong?
6 Answers, 1 is accepted
0
Hello Bjorn,
Maya
Telerik
Currently, DisplayIndex property of the tile is not a dependency one and you cannot bind it. That is why you are getting such error. We will consider changing it to dependency property, but for the time being it is just a regular CLR property.
Maya
Telerik
TRY TELERIK'S NEWEST PRODUCT - EQATEC APPLICATION ANALYTICS for WPF.
Learn what features your users use (or don't use) in your application. Know your audience. Target it better. Develop wisely.
Sign up for Free application insights >>
Learn what features your users use (or don't use) in your application. Know your audience. Target it better. Develop wisely.
Sign up for Free application insights >>
0
Muhammad Ummar
Top achievements
Rank 1
answered on 27 May 2014, 07:44 AM
Hello Maya,
I need to save the DisplayIndex to database so I can set a position of Tile next time it gets loaded. I want to know how can I update the ViewModel's property when DisplayIndex is changed using Drag and Drop operation? I know it is not a dependency property so data binding wouldn't be possible, any other workaround for this problem?
Regards
Ummar
I need to save the DisplayIndex to database so I can set a position of Tile next time it gets loaded. I want to know how can I update the ViewModel's property when DisplayIndex is changed using Drag and Drop operation? I know it is not a dependency property so data binding wouldn't be possible, any other workaround for this problem?
Regards
Ummar
0
Hello Ummar,
We will need a little more time to think of a possible workaround. We will get back to you as soon as possible.
Regards,
Boris Penev
Telerik
We will need a little more time to think of a possible workaround. We will get back to you as soon as possible.
Regards,
Boris Penev
Telerik
Check out Telerik Analytics, the service which allows developers to discover app usage patterns, analyze user data, log exceptions, solve problems and profile application performance at run time. Watch the videos and start improving your app based on facts, not hunches.
0
Hello Ummar,
A possible approach for fulfilling your requirement is to attach a OnDrop() handler to the TileList by using the DragDropManager.AddDropHandler() method. In that handler you will need to get all the Tiles of the TileList by using the ChildrenOfType<Tile>() extension method. Then get the business object for each tile by using its DataContext property and set DisplayIndex property of your Business object to the DisplayIndex property of the Tile.
In order to load initially in any particular order the tiles, you can use the AutoGeneratingTile event of the TileList.
Please examine the attached a sample project that demonstrates the suggested approach and let us know if this helps.
Regards,
Boris Penev
Telerik
A possible approach for fulfilling your requirement is to attach a OnDrop() handler to the TileList by using the DragDropManager.AddDropHandler() method. In that handler you will need to get all the Tiles of the TileList by using the ChildrenOfType<Tile>() extension method. Then get the business object for each tile by using its DataContext property and set DisplayIndex property of your Business object to the DisplayIndex property of the Tile.
In order to load initially in any particular order the tiles, you can use the AutoGeneratingTile event of the TileList.
Please examine the attached a sample project that demonstrates the suggested approach and let us know if this helps.
Regards,
Boris Penev
Telerik
Check out Telerik Analytics, the service which allows developers to discover app usage patterns, analyze user data, log exceptions, solve problems and profile application performance at run time. Watch the videos and start improving your app based on facts, not hunches.
Joshua
commented on 16 Jul 2021, 12:58 AM
Top achievements
Rank 1
The problem with manually attaching an OnDrop handler is that none of the state is updated yet. You have to post another delegate to the Dispatcher to get out of the callstack and let the state update first.
0
Muhammad Ummar
Top achievements
Rank 1
answered on 05 Jun 2014, 01:15 PM
Hello Boris,
Thanks for your reply and helpful code example, it worked. THANKS.
But my scenario is little bit different as I am also using the Grouping of tiles, the approach you described worked fine in grouping case as well. But the DisplayIndex printed in OnDrop event handler are not as expected, in fact they contain the wrong values. but visually every thing is fine. Just for my understanding I have updated your project with Group functionality, and added 8 more tiles along with 4 your tiles (means total 12 tiles) divided in 3 groups. So the DisplayIndex renage in 0-11. but when I drag/drop any tile the printed DisplayIndex also contains the wrong values even 26 and 27, which is not possible. Following are the code updates so you can test
The Business object is
The updated Main window code is
and finally the code behind for Main window is
Run the code and Drag any tile and Drop it to some other group, on the debug console you will see the wrong entries of DisplayIndex. and each time you drag tiles you will see DisplayIndex increasing.
Just a reminder that visually every thing works fine and on next reload the tiles appear in correct position. but I am wondering about wrong values of DisplayIndex? Could you please clarify?
Thanks for your reply and helpful code example, it worked. THANKS.
But my scenario is little bit different as I am also using the Grouping of tiles, the approach you described worked fine in grouping case as well. But the DisplayIndex printed in OnDrop event handler are not as expected, in fact they contain the wrong values. but visually every thing is fine. Just for my understanding I have updated your project with Group functionality, and added 8 more tiles along with 4 your tiles (means total 12 tiles) divided in 3 groups. So the DisplayIndex renage in 0-11. but when I drag/drop any tile the printed DisplayIndex also contains the wrong values even 26 and 27, which is not possible. Following are the code updates so you can test
The Business object is
001./// <summary>002. /// A football club.003. /// </summary>004. public class Club : INotifyPropertyChanged005. {006. public event PropertyChangedEventHandler PropertyChanged;007. 008. private string name;009. private int? displayIndex;010. 011. public int? DisplayIndex012. {013. get { return this.displayIndex; }014. set015. {016. if (value != this.displayIndex)017. {018. this.displayIndex = value;019. this.OnPropertyChanged("DisplayIndex");020. }021. }022. }023. 024. public string Name025. {026. get { return this.name; }027. set028. {029. if (value != this.name)030. {031. this.name = value;032. this.OnPropertyChanged("Name");033. }034. }035. }036. 037. private string _tileGroup;038. 039. public string TileGroup040. {041. get { return _tileGroup; }042. set043. {044. _tileGroup = value;045. OnPropertyChanged("TileGroup");046. }047. }048. 049. 050. public Club()051. {052. 053. }054. 055. public Club(string name, int displayIndex, string groupHeader)056. {057. this.name = name;058. this.displayIndex = displayIndex;059. TileGroup = groupHeader;060. }061. 062. protected virtual void OnPropertyChanged(PropertyChangedEventArgs args)063. {064. PropertyChangedEventHandler handler = this.PropertyChanged;065. if (handler != null)066. {067. handler(this, args);068. }069. }070. 071. private void OnPropertyChanged(string propertyName)072. {073. this.OnPropertyChanged(new PropertyChangedEventArgs(propertyName));074. }075. 076. public override string ToString()077. {078. return this.Name;079. }080. 081. public static ObservableCollection<Club> GetClubs()082. {083. ObservableCollection<Club> clubs = new ObservableCollection<Club>();084. Club club;085. 086. // Liverpool087. club = new Club("Liverpool", 3, "Group1");088. clubs.Add(club);089. 090. // Manchester Utd.091. club = new Club("Manchester Utd.", 2, "Group1");092. clubs.Add(club);093. 094. // Chelsea095. club = new Club("Chelsea", 0, "Group1");096. clubs.Add(club);097. 098. // Arsenal099. club = new Club("Arsenal", 1, "Group1");100. clubs.Add(club);101. 102. // Liverpool103. club = new Club("Liverpool-Group2", 7, "Group2");104. clubs.Add(club);105. 106. // Manchester Utd.107. club = new Club("Manchester Utd-Group2.", 6, "Group2");108. clubs.Add(club);109. 110. // Chelsea111. club = new Club("Chelsea-Group2", 4, "Group2");112. clubs.Add(club);113. 114. // Arsenal115. club = new Club("Arsenal-Group2", 5, "Group2");116. clubs.Add(club);117. 118. // Liverpool119. club = new Club("Liverpool-Group3", 11, "Group3");120. clubs.Add(club);121. 122. // Manchester Utd.123. club = new Club("Manchester Utd-Group3.", 10, "Group3");124. clubs.Add(club);125. 126. // Chelsea127. club = new Club("Chelsea-Group3", 8, "Group3");128. clubs.Add(club);129. 130. // Arsenal131. club = new Club("Arsenal-Group3", 9, "Group3");132. clubs.Add(club);133. 134. return clubs;135. }136. }The updated Main window code is
01.<Window x:Class="RadTileList_WPF_DisplayIndex.MainWindow"03. xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"04. xmlns:telerik="http://schemas.telerik.com/2008/xaml/presentation"05. xmlns:my="clr-namespace:RadTileList_WPF_DisplayIndex"06. Title="MainWindow" Height="700" Width="700">07. <Window.Resources>08. <my:MyViewModel x:Key="MyViewModel"/>09. </Window.Resources>10. <Grid DataContext="{StaticResource MyViewModel}">11. <Grid.RowDefinitions>12. <RowDefinition Height="*"/>13. <RowDefinition Height="Auto" />14. </Grid.RowDefinitions>15. <telerik:RadTileList x:Name="tileList"16. ItemsSource="{Binding Clubs}"17. AutoGeneratingTile="tileList_AutoGeneratingTile"18. ScrollViewer.HorizontalScrollBarVisibility="Visible">19. <telerik:RadTileList.GroupTemplate>20. <DataTemplate>21. <TextBlock Margin="0,0,0,10" Text="{Binding}" FontSize="16"></TextBlock>22. </DataTemplate>23. </telerik:RadTileList.GroupTemplate>24. </telerik:RadTileList>25. </Grid>26.</Window>and finally the code behind for Main window is
01.using System;02.using System.Collections.Generic;03.using System.Linq;04.using System.Text;05.using System.Windows;06.using System.Windows.Controls;07.using System.Windows.Data;08.using System.Windows.Documents;09.using System.Windows.Input;10.using System.Windows.Media;11.using System.Windows.Media.Imaging;12.using System.Windows.Navigation;13.using System.Windows.Shapes;14.using Telerik.Windows.Controls;15.using System.Diagnostics;16.using Telerik.Windows.DragDrop;17. 18.namespace RadTileList_WPF_DisplayIndex19.{20. /// <summary>21. /// Interaction logic for MainWindow.xaml22. /// </summary>23. public partial class MainWindow : Window24. {25. public MainWindow()26. {27. InitializeComponent();28. DragDropManager.AddDropHandler(this.tileList, OnDrop);29. }30. 31. private void OnDrop(object sender, Telerik.Windows.DragDrop.DragEventArgs e)32. {33. e.Handled = true;34. var tiles = this.tileList.ChildrenOfType<Tile>();35. foreach (Tile tile in tiles)36. {37. Club club = tile.DataContext as Club;38. club.DisplayIndex = tile.DisplayIndex;39. Debug.WriteLine("Name: " + club.Name + "; DisplayIndex: " + club.DisplayIndex);40. }41. }42. 43. private void tileList_AutoGeneratingTile(object sender, AutoGeneratingTileEventArgs e)44. {45. e.Tile.DisplayIndex = (e.Tile.DataContext as Club).DisplayIndex;46. e.Tile.Group = (e.Tile.DataContext as Club).TileGroup;47. }48. }49.}Run the code and Drag any tile and Drop it to some other group, on the debug console you will see the wrong entries of DisplayIndex. and each time you drag tiles you will see DisplayIndex increasing.
Just a reminder that visually every thing works fine and on next reload the tiles appear in correct position. but I am wondering about wrong values of DisplayIndex? Could you please clarify?
0
Hello Ummar,
Thank you for reporting this issue. We reviewed the TileList control and we can confirm that the reported behavior is actually a bug. We logged it in our feedback portal where you can track its status. We also updated your Telerik account points as a thanks for your cooperation in reporting this issue.
Regards,
Boris Penev
Telerik
Thank you for reporting this issue. We reviewed the TileList control and we can confirm that the reported behavior is actually a bug. We logged it in our feedback portal where you can track its status. We also updated your Telerik account points as a thanks for your cooperation in reporting this issue.
Regards,
Boris Penev
Telerik
Check out Telerik Analytics, the service which allows developers to discover app usage patterns, analyze user data, log exceptions, solve problems and profile application performance at run time. Watch the videos and start improving your app based on facts, not hunches.