This is a migrated thread and some comments may be shown as answers.

RadTreeViewItem DefaultImageSrc in CODE

16 Answers 294 Views
TreeView
This is a migrated thread and some comments may be shown as answers.
Tim
Top achievements
Rank 1
Tim asked on 21 Jul 2009, 07:47 PM
Plenty of examples for xaml, I need to know how to set the DefaultImageSrc in code -- no combination of path works for me.

The following XAML works, taken from the LoadOnDemand example:

        <DataTemplate x:Key="FoldersTemplate"
            <StackPanel Orientation="Horizontal"
                <Image Margin="2,0,2,0"  Source="images/tree/folder.png"/> 
                <TextBlock Text="{Binding Leaf}" /> 
            </StackPanel> 
        </DataTemplate> 

However, the following .cs does not:

RadTreeViewItem folderTreeViewItem = new RadTreeViewItem() { Header = LeafDefaultImageSrc = "images/tree/folder.png" }; 
 

I've tried:

images/tree/folder.png
/images/tree/folder.png
../images/tree/folder.png
../../images/tree/folder.png

plus I spent 20 minutes on Google with no real answer.  The help (http://www.telerik.com/help/silverlight/telerik.windows.controls.navigation-telerik.windows.controls.radtreeviewitem-defaultimagesrc.html) doesn't offer any clue as to what the path should actually be.

Thanks,
Tim


16 Answers, 1 is accepted

Sort by
0
Bobi
Telerik team
answered on 22 Jul 2009, 01:24 PM
Hi Tim,

We deeply apologize for the caused inconvenience. Your Telerik points are updated with 1000.

For now DefaultImageSrc is a property of string type and represent the RelativeOrAbsolute path to the image . If the image is in the main folder and its build action is Resource then you simply have to write for example:
       
                      DefaultImageSrc = "image.jpg";

In you are using code behind then you have to set this property in the Usercontrol constructor.

                       this.item.DefaultImageSrc = "image.jpg";

Unfortunately you are not able to set DefaultImageSrc in code behind after the item is initialized unless it has some previous value.
This issue will be fixed immediately  and the change will be reflected in  the upcoming SP1 release .  As a workaround for now you can use something like for example:

             this.item.DefaultImageSrc = "";
             this.item.DefaultImageSrc = "image.jpg";
or

         XAML
        <telerik:RadTreeViewItem x:Name="item" Header="Item2" DefaultImageSrc="image.jpg" />
        
          C#
          this.item.DefaultImageSrc = "newimage.jpg";
or
set in some way default values for DefaultImageSrc  and after that you can change the image to whatever you want.


Greetings,
Boryana
the Telerik team

Instantly find answers to your questions on the new Telerik Support Portal.
Check out the tips for optimizing your support resource searches.
0
Tim
Top achievements
Rank 1
answered on 22 Jul 2009, 02:20 PM
Either I do not understand you, or your proposal does not work.  I do not have xaml-declared RadTreeViewItems - the tree is declared and the items are created in the code-behind.  Imagine Windows File Explorer, it might have something like this:

SelectFolder.xaml: 
 
<T:RadTreeView  
  IsRootLinesEnabled="True"  
  IsLineEnabled="True"  
  x:Name="FolderSelectionTree"  
  PreviewSelected="TreeView_PreviewSelected"/> 
   

With code-behind like this:
SelectFolder.xaml.cs: 
 
  this.Dispatcher.BeginInvoke(() => 
    { 
      FolderSelectionTree.Items.Add(BuildCandidateFolderTreeView(folders)); 
    }); 
     
    private static RadTreeViewItem BuildCandidateFolderTreeView(List<FolderInfo> folders) 
    { 
        RadTreeViewItem driveNode = new RadTreeViewItem { Header = StringResources.DC }; 
        driveNode.DefaultImageSrc = ""
        driveNode.DefaultImageSrc = "images/tree/volume.png"
 
        foreach (string folderName in folders.Select(...)) 
        { 
            RadTreeViewItem folderTreeViewItem = new RadTreeViewItem() { Header = folderName }; 
            folderTreeViewItem.DefaultImageSrc = ""
            folderTreeViewItem.DefaultImageSrc = "images/tree/folder.png"
            driveNode.Items.Add(folderTreeViewItem); 
        } 
         
        return driveNode; 
    } 
 

There are two places in the code-behind that create the RadTreeViewItem objects and I tried not initializing them at construction time, and then setting them to "" and finally to the actual image.  images/tree/folder.png is the path relative to the xaml file.  Please tell me how to apply your logic to this exact example.  I can wait for the real solution in SP1, ultimately, but I have to make screen shots for my boss to demo soon and it would be really nice if the icons showed up in my tree.

Thanks,
Tim



0
Tim
Top achievements
Rank 1
answered on 22 Jul 2009, 05:06 PM
I would also be OK to use the LeagueDataTemplateSelector solution from the demo - I tried it, and the tree in fact has the ItemTemplateSelector set to my class, but it does not appear to ever call SelectTemplate().  The demo works fine - I can see it hit a breakpoint in SelectTemplate for the demo, but not my code.

Does it have to do with the DataSource vs building in code-behind?

Thanks,
Tim



0
Bobi
Telerik team
answered on 23 Jul 2009, 01:50 PM
Hello Tim,

We apologize for the caused inconvenience please download the latest assemblies from the last internal build v2.0.50727. In the official release DefautImageSrc  is not working correctly but this issue is fixed in the internal build v2.0.50727.

Please find attached a sample project that shows how to set DefautImageSrc of dinamically created TreeView in code behind.

You have to use Dispatcher when setting the  DefaultImageSrc :
 
  driveNode.Dispatcher.BeginInvoke(() => driveNode.DefaultImageSrc = "folder.png");

As to the second question you can use the demo but you have to do the following in order to work properly:

1.Add some datatemplates in the resources of your usercontrol the most important is not to forget LeagueDataTemplateSelector :

  <UserControl.Resources>

        <ds:LeaguesDataSource x:Key="MyList" />
        <local:LeagueDataTemplateSelector x:Key="myDataTemplateSelector" />

        <DataTemplate x:Key="Team">
            <StackPanel Orientation="Horizontal">
                <Image Source="{Binding Image}" Margin=" 0,0,6,0"/>
                <TextBlock Text="{Binding Name}" Foreground="Blue" FontWeight="Bold" FontSize="9" />
            </StackPanel>
        </DataTemplate>

        <core:HierarchicalDataTemplate x:Key="Division" ItemsSource="{Binding Teams}">
            <StackPanel Orientation="Horizontal">
                <Image Source="{Binding Image}" Margin=" 0,0,6,0" />
                <TextBlock Text="{Binding Name}" Foreground="Green"  FontWeight="Bold" FontSize="12" />
            </StackPanel>
        </core:HierarchicalDataTemplate>

        <core:HierarchicalDataTemplate x:Key="League" ItemsSource="{Binding Divisions}">
            <StackPanel Orientation="Horizontal">
                <Image Source="{Binding Image}" Margin=" 0,0,6,0" />
                <TextBlock Text="{Binding Name}" Foreground="Black" FontWeight="Bold" FontSize="15" />
            </StackPanel>
        </core:HierarchicalDataTemplate>
    </UserControle.Resources>

2.Set ItemTemplateSelector of RadTreeView
<telerikNavigation:RadTreeView Width="290" HorizontalAlignment="Left" VerticalAlignment="Top"
                ItemTemplateSelector="{StaticResource myDataTemplateSelector}"
                 />
3.Add some ItemsSource to the TreeView either in XAML or Code Behind.
If you want to use different itemtemplates then you need to set some datasource to the Treeview.

I hope that this will help you if not please send us any sample project in order to fix it.
 Please let us know if you have any other questions.

All the best,
Boryana
the Telerik team

Instantly find answers to your questions on the new Telerik Support Portal.
Check out the tips for optimizing your support resource searches.
0
Tim
Top achievements
Rank 1
answered on 23 Jul 2009, 03:46 PM
Hi Boryana,

First off, thank you for your prompt replies. 

Second, I can confirm that v2.0.50727 does resolve the problem of

new RadTreeViewItem {Header = "Root", DefaultImageSrc = "images/tree/computer.png"};

for the simple example below.  I even used the Q2 release to ensure it was still broken (it was.)

    public partial class Page : UserControl 
    { 
        public Page() 
        { 
            InitializeComponent(); 
            Loaded += new System.Windows.RoutedEventHandler(Page_Loaded); 
        } 
 
        void Page_Loaded(object sender, System.Windows.RoutedEventArgs e) 
        { 
            Dispatcher.BeginInvoke(() => FolderView.Items.Add(BuildTreeView())); 
        } 
 
        private static RadTreeViewItem BuildTreeView() 
        { 
            RadTreeViewItem rootNode = new RadTreeViewItem 
                                           {Header = "Root", DefaultImageSrc = "images/tree/computer.png"}; 
            return rootNode; 
        } 
    } 
 

It does not fix my production application.  The only obvious (to me) difference is that instead of invoking my BuildTreeView() method in the Loaded event handler, it is built from a WCF asynchronous callback method, although in both cases using Dispatcher.BeginInvoke().

You have to use Dispatcher when setting the  DefaultImageSrc :
 
  driveNode.Dispatcher.BeginInvoke(() => driveNode.DefaultImageSrc = "folder.png");

Why would I need to set the DefaultImageSrc using the dispatcher when the entire tree itself is constructed and set in the Dispatcher context?  Doesn't that end up double-dispatching?  It works as I would expect above.

Thirdly, as I said, but did not quote code, using the league example, I do in fact show (in the debugger) that the ItemTemplateSelector property of the RadTreeView is set to the class declared as a resource (in my case, it is shared, so I have it in App.xaml).   This one line:

If you want to use different itemtemplates then you need to set some datasource to the Treeview.

caught my interest -- can I only use the template selector with a DataSource?  I have none - all my data comes from asynchronous WCF services.  Alas I haven't pared it down enough where I can build you a non-proprietary example that I can attach.

Any other ideas?

Tim




0
Tim
Top achievements
Rank 1
answered on 23 Jul 2009, 04:21 PM
OK, I found out what was different in production - the deployment system was deploying the Q2 release and not the binaries that I had referenced.  That problem (DefaultImageSrc) is solved.  I'd still like to understand the ItemTemplateSelector problem though.

Tim

0
Bobi
Telerik team
answered on 24 Jul 2009, 01:00 PM
Hello Tim,

The DataTemplateSelector enables you to specify your own custom logic that determines which DataTemplate should be applied to each item, so this means that you need to have some itemtemplate for every item.

In your case you have:

 FolderSelectionTree.Items.Add(BuildCandidateFolderTreeView(folders));

This is dynamically population of the treeview without using ItemsSource or Itemtemplate, so in this case you can not use
ItemTemplateSelector because you do not apply any datatemplate .

By DataSource I mean to use ItemsSource property of the RadTreeView.
If you set some DataTemplates and ItemSource  to the treeview either in XMAL or CodeBehind then you can use
ItemTemplateSelector.

My suggestion is to create  some DataTemplates for the TemplateSelector and populate the TreeView with the data from the WCF service by using the ItemsSource property.
For more information how to populate RadTreeView from WCF service using a hierarchical data template please visit the following article:

http://blogs.telerik.com/kirilstanoev/posts/08-08-27/Populating_Silverlight_TreeView_from_WCF_Service_with_LINQ_to_SQL.aspx

I hope that this will help you.
Please let us know if you have any other questions.

Best wishes,
Boryana
the Telerik team

Instantly find answers to your questions on the new Telerik Support Portal.
Check out the tips for optimizing your support resource searches.
0
Tim
Top achievements
Rank 1
answered on 24 Jul 2009, 01:09 PM
OK, that makes sense.  Let me as you what I think is an obvious question -- If I have to use ItemSource, that implies that my actual data objects (DTOs if you will) are the items the tree displays.  The templates refer to properties for the item, and any child nodes.

Why do I need to write the logic for template selection in code when it could be inferred from the run-time type of the object?  In other words, make the HierchicalDataTemplate / DataTemplate have a type or typename property which says "I render objects of this type"?

Tim

0
Miroslav
Telerik team
answered on 24 Jul 2009, 01:53 PM
Hi Tim,

Yes, it is very common to have a switch over the data item type to select templates. For this purpose in WPF there is the DataType property found on the DataTemplate. Unfortunately we could not create this in Silverlight because we could not achieve their automatic inheritance. Also the Xaml syntax is very inflexible and you cannot place a Type property that can be written in any reasonable way in xaml (i.e. you will need the full type name to specify the type). The "TargetType" property seems to be treated differently by the xaml reader.

Selectors are powerful but if you want to change something based on a property of the control, better use a binding to this property with an appropriate value converter. In your case it seems this is the type of the control, so it will not be possible.

All the best,
Miroslav
the Telerik team

Instantly find answers to your questions on the new Telerik Support Portal.
Check out the tips for optimizing your support resource searches.
0
Miroslav
Telerik team
answered on 24 Jul 2009, 02:29 PM
Hello Tim,

I just found a simple typed template selector than can be used easily in xaml. It is not very powerful (simple type name checks) but you can extended it to fit your needs if necessary.

I have attached a project with it here.

Hopefully it will be helpful for you.

Sincerely yours,
Miroslav
the Telerik team

Instantly find answers to your questions on the new Telerik Support Portal.
Check out the tips for optimizing your support resource searches.
0
Tim
Top achievements
Rank 1
answered on 26 Aug 2009, 05:01 PM
I have finally achieved what I wanted to achieve.  I modified the load-on-demand example attached earlier to have a DataTemplateSelector, and wanted to upload it to this thread for archival purposes.  How do I do that?

This example supports:
LoadOnDemand
Multiple ItemTemplates at the same level based on the type of the ItemsSource item using DataTemplateSelector

Important point: You cannot explicitly list the ItemTemplate property of a parent node if you want your DataTemplateSelector to be called

Tim

0
Nikolay
Telerik team
answered on 31 Aug 2009, 07:57 AM
Hello Tim,

You cannot attach files to the forum threads. You can open a support ticket and attach the files there. I hope that this will not cause you any inconvenience.

Sincerely yours,
Nick
the Telerik team

Instantly find answers to your questions on the new Telerik Support Portal.
Watch a video on how to optimize your support resource searches and check out more tips on the blogs.
0
Shura111
Top achievements
Rank 1
answered on 09 Nov 2009, 10:33 AM
Dynamic assignment of "DefaultImageSrc" property in the code behind really was fixed in that build, and it still works fine in Q3 Release for the RadTreeView component. But not for the new RadTreeListView, when I tried to move to it! :(
We dynamically build items tree in the code behind (without assigning ItemsSource) because the data arrive from asynchronous WCF service call and are stored locally in smth like "client dataset".

 

 

    private void tv_ItemPrepared(object sender, RadTreeViewItemPreparedEventArgs e)  
    {  
      RadTreeListViewItem it = e.PreparedItem as RadTreeListViewItem;  
      string imageName = String.Empty;  
      if (it.HasItems)  
        imageName = "Node.png";  
      else 
        imageName = "Item.png";  
      it.DefaultImageSrc = imageName;  
    }  
 

(ImagesBaseDir is set in XAML)

Well, I managed to fix this with RadColumn.CellTemplateSelector and two templates, but IMHO setting item image in ItemPrepared handler is more elegant

 

0
Bobi
Telerik team
answered on 12 Nov 2009, 01:07 PM
Hi Shura111,

We apologize for the caused inconvenience. Thank you for the feedback. Your Telerik points are updated.
This issue will be fixed as soon as possible.

Best wishes,
Boryana
the Telerik team

Instantly find answers to your questions on the new Telerik Support Portal.
Watch a video on how to optimize your support resource searches and check out more tips on the blogs.
0
Manny
Top achievements
Rank 1
answered on 17 Dec 2009, 03:10 PM
Hi All,

I had similar problem, I have treeview where images are not showing. This is true regardless of whether I create nodes programmatically or in XAML.

After much futzing it finally occurred to me to check IIS logs. Check this out:

1. My setting in XAML for ImagesBaseDir. Notice the relative path:
    <telerikNavigation:RadTreeView ItemContainerStyle="{StaticResource TreeViewItemStyle}"
                                   ImagesBaseDir="/../rg2Images/"
                                   IsExpandOnSingleClickEnabled="True"
                                   ExpanderStyle="{StaticResource ExpanderStyle}"
                                   x:Name="rtvData">

2. The actual query in IIS log. Note the 401 Not Found:
2009-12-17 14:58:21 ::1 GET /ArchG2.Portal/rg2Silverlight/rg2Images/nba_la_lakers.png - 7280 - ::1 Mozilla/4.0+(compatible;+MSIE+7.0;+Windows+NT+6.0;+WOW64;+Trident/4.0;+SLCC1;+.NET+CLR+2.0.50727;+.NET+CLR+3.5.30729;+.NET+CLR+3.0.30729;+InfoPath.2;+OfficeLiveConnector.1.4;+OfficeLivePatch.1.3) 401 2 5 12

Hmm, that relative path is gone. So next we simply create a virtual directory underneath the silverlight XAP home that references the real images. Now the queries work Just Fine (304 Unchanged is a great return code):
2009-12-17 15:07:59 ::1 GET /ArchG2.Portal/rg2Silverlight/rg2Images/Edit_back.gif - 7280 radxsoftware\andy.bruce ::1 Mozilla/4.0+(compatible;+MSIE+7.0;+Windows+NT+6.0;+WOW64;+Trident/4.0;+SLCC1;+.NET+CLR+2.0.50727;+.NET+CLR+3.5.30729;+.NET+CLR+3.0.30729;+InfoPath.2;+OfficeLiveConnector.1.4;+OfficeLivePatch.1.3) 304 0 0 2

The moral:
a. The ImagesBaseDir is relative to the "root" of the XAP not the application (which confused me--when I read "root" for a Web application I think the Web application root!).

b. ImagesBaseDir does not support relative paths. Of course, if you construct your own Web request then you can use relative paths but that isn't possible with TreeView.

Hope this helps someone else out...

Andy
0
Valentin.Stoychev
Telerik team
answered on 21 Dec 2009, 07:48 AM
Hi Manny,

Thanks for sharing this. Yes - working with images is quite different from the way we get used to with the html pages. More info on the topic is available here:
http://blogs.telerik.com/valentinstoychev/posts/08-10-02/loading_images_in_silverlight2_applications.aspx

Greetings,
Valentin.Stoychev
the Telerik team

Instantly find answers to your questions on the new Telerik Support Portal.
Watch a video on how to optimize your support resource searches and check out more tips on the blogs.
Tags
TreeView
Asked by
Tim
Top achievements
Rank 1
Answers by
Bobi
Telerik team
Tim
Top achievements
Rank 1
Miroslav
Telerik team
Nikolay
Telerik team
Shura111
Top achievements
Rank 1
Manny
Top achievements
Rank 1
Valentin.Stoychev
Telerik team
Share this question
or