
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 : INotifyPropertyChanged
005.
{
006.
public
event
PropertyChangedEventHandler PropertyChanged;
007.
008.
private
string
name;
009.
private
int
? displayIndex;
010.
011.
public
int
? DisplayIndex
012.
{
013.
get
{
return
this
.displayIndex; }
014.
set
015.
{
016.
if
(value !=
this
.displayIndex)
017.
{
018.
this
.displayIndex = value;
019.
this
.OnPropertyChanged(
"DisplayIndex"
);
020.
}
021.
}
022.
}
023.
024.
public
string
Name
025.
{
026.
get
{
return
this
.name; }
027.
set
028.
{
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
TileGroup
040.
{
041.
get
{
return
_tileGroup; }
042.
set
043.
{
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.
// Liverpool
087.
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.
// Chelsea
095.
club =
new
Club(
"Chelsea"
, 0,
"Group1"
);
096.
clubs.Add(club);
097.
098.
// Arsenal
099.
club =
new
Club(
"Arsenal"
, 1,
"Group1"
);
100.
clubs.Add(club);
101.
102.
// Liverpool
103.
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.
// Chelsea
111.
club =
new
Club(
"Chelsea-Group2"
, 4,
"Group2"
);
112.
clubs.Add(club);
113.
114.
// Arsenal
115.
club =
new
Club(
"Arsenal-Group2"
, 5,
"Group2"
);
116.
clubs.Add(club);
117.
118.
// Liverpool
119.
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.
// Chelsea
127.
club =
new
Club(
"Chelsea-Group3"
, 8,
"Group3"
);
128.
clubs.Add(club);
129.
130.
// Arsenal
131.
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_DisplayIndex
19.
{
20.
/// <summary>
21.
/// Interaction logic for MainWindow.xaml
22.
/// </summary>
23.
public
partial
class
MainWindow : Window
24.
{
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.