locked
Possible to tie CXML data to Basic Adorners? RRS feed

  • General discussion

  • I have used Tony Champion's blog about making a adorner (very informative and useful)

    http://tonychampion.net/blog/index.php/2012/01/pivotviewer-basics-basic-item-adorners/

    I'm trying to understand how to tie a website link that can be found in my CXML to the adorner that so a little button link will show up at the top right of the pivot item and when clicked it will bring up a pop up. Can you do that? Are you able to tie CXML data to the adorners? If so how do you do that?

    Wednesday, March 14, 2012 3:20 PM

All replies

  • For example

        public partial class MainPage : UserControl
        {
            string CXML_PATH = "http://140.90.120.110/demo2/SilverlightApplication1.Web/ClientBin/SOR.cxml";
            CxmlCollectionSource _cxml;
    
            public MainPage()
            {
                InitializeComponent();
                pv.Loaded += new RoutedEventHandler(pvViewer_Loaded);
            }
    
            void pvViewer_Loaded(object sender, RoutedEventArgs e)
            {
                _cxml = new CxmlCollectionSource(new Uri(CXML_PATH, UriKind.Absolute));
                _cxml.StateChanged += new EventHandler<CxmlCollectionStateChangedEventArgs>(_cxml_StateChanged);
            }
    
            void _cxml_StateChanged(object sender, CxmlCollectionStateChangedEventArgs e)
            {
                if (e.NewState == CxmlCollectionState.Loaded)
                {
                    pv.PivotProperties = _cxml.ItemProperties.ToList();
                    pv.ItemTemplates = _cxml.ItemTemplates;
                    pv.ItemsSource = _cxml.Items;
                }
            }
    
            private void GetCommands(object sender, PivotViewerCommandsRequestedEventArgs e)
            {
                PivotViewerItem item = _cxml.GetItemById("3");
                e.Commands.Add(new TopRightLinks(e.Item as WebsiteLink));
            }
        }

    Currently my function GetCommands adds an adorner to the top right corner. I want to be able to grab the current PivotItem selected "PivotViewerItem item = _cxml.GetItemById("3");" and pass the url to TopRightLinks, currently I'm just passing a e.Item as a WebsiteLink but it does nothing. I'm not quite sure why I needed to pass the e.Item in there yet. I guess its just a place holder for now until I can create a type WebsiteLink which is a class I have created that holds a name and uri.

    Wednesday, March 14, 2012 4:35 PM
  • I think I found something but I'm not sure if it is the correct way pv.SelectedItem? That will give me the current selected item, how do I display what the object contains? Am I doing this wrong? Does anyone know?

    Thursday, March 15, 2012 4:00 PM
  • I think I found something but I'm not sure if it is the correct way pv.SelectedItem?

    It's the right way.  But I am not familar about pivotview. It would be help if you provide the sample. And we can resolve through it.

     

    Friday, March 16, 2012 6:34 AM
  • Thanks for you reply.

    Okay so I took a screenshot to explain what I want.

    What I'm talking about is in red highlighted.

    I added my adorner which is located on the top right corner of SWiM. What I want that adorner to do is when its clicked it will bring up the website which could be found in the CXML highlight on the right panel.

    With the code pasted above, I was thinking that pv.SelectedItem would work but it returns an object but I don't know what to do with that object in order to get the URL off the CXML. How do I parse that object to get my the URL?

    Is there a better way of doing this? Without needing to selected the specific item before getting the URL? I was hoping that all the items would have the website URL loaded on the adorner when the pivotviewer page loads.

    Friday, March 16, 2012 10:40 AM
  • You can get the object being used for the item adorner from the e.Item property of the PivotViewerCommandsRequestedEventArgs varible being passed to the event handler.  This is a better approach than using SelectedItem, because you can have an item adorner appear on mouse-overs as well as when the item is selected.

    If you are using a CXML collection being parsed by the CxmlCollectionSource class, then the e.Item will be a PivotViewerItem class.  The structure is a bit strange, but basically you can access all of your properties via a string index off of the main item.  Each property will return an array of the given type (ie string, doubles, DateTime).  This is so it can handle multi-valued properties.  So if you only have a single value, if will be at index 0.

    For example, if you wanted to access the 'Href' property, you would do so by:

    var item = e.Item as PivotViewerItem;
    var href = item["Href"][0];

    Let me know if you have any questions.

     

    Saturday, March 17, 2012 10:38 AM
  • You can get the object being used for the item adorner from the e.Item property of the PivotViewerCommandsRequestedEventArgs varible being passed to the event handler.  This is a better approach than using SelectedItem, because you can have an item adorner appear on mouse-overs as well as when the item is selected.

    Right I was worried about that, thanks for pointing that out!

    This leads me with a question and an issue I've been having.

    Question

    Is reading CXML even a smart thing to do anymore with pivotviewer v2?It doesn't seem like there are lots of guide there teaching you how to do this, most of which create their own dynamically.

    I have seen them make an ObservableCollection of their own class and then adding that collection to the ItemsSource.

    What is the best way?

    Issue

    Upgrade to silverlight 5, I noticed that since upgrading my code to use CxmlCollectionSource to load my CXML, when I run the pivotviewer none of the items show up, it is not until I click on a filter that my items will show up. Why is that? Am I missing a statechange that would detect that the pivot window itself is loaded there for show the items?

    Thanks again Tony for your reply to the last question of mine.

    Monday, March 19, 2012 10:17 AM
  • var item = e.Item as PivotViewerItem; var href = item["Href"][0];

    Is the Href the name of the facet you are trying to access?

            <Facet Name="System Webpage">
              <Link Name="http://www.airdat.com/" Href="http://www.airdat.com/" />
              <Link Name="http://amdar.noaa.gov/" Href="http://amdar.noaa.gov/" />
            </Facet>

    Doing

            private void GetCommands(object sender, PivotViewerCommandsRequestedEventArgs e)
            {
                var item = e.Item as PivotViewerItem;
                var href = item["System Webpage"][0];
                WebsiteLink link = new WebsiteLink();
                link.Url = href as string;
    
                e.Commands.Add(new TopRightLinks(link));
            }

    I don't seem to be getting my URLs, is there a way to debug this? I never really programmed C# before so I don't know if there is a way to print out what item is or something to let me know if its a var assignment issue or a cxml issue.

    Monday, March 19, 2012 11:40 AM
  • My cxml scheme is

    <Item/>

       <Description/>

       <Facets/>

    I did do a test with

    var item = e.Item as PivotViewerItem;

    var href = item["Description"][0]

    And it got me the description, not sure how to get to the Facets.

    I have tried

    var href = item["Facet Name='System Webpage'"][0]

    with no luck.

    Monday, March 19, 2012 11:58 AM
  •     <Item Id="2" Img="NFS_6885_GLOSS.jpg" Name="Global Ocean Observing System (GOOS) Global Sea Level Observing System" Href="https://casanosa.noaa.gov/survey/summary.php?group_id=47&amp;instance_id=214">
          <Description>US contribution to the 170 GLOSS (Global Sea Level Observing System) tide gauges for climate. GLOSS stations are fixed platforms on islands and in the coastal zone that measure and report sea level information in real- and near-real time using geostationary satellites and the GTS. Mission: GLOSS is designed to provide global sea level information for use in multiple NOAA missions including climate monitoring and prediction and studies of climate phenomena such as ENSO.</Description>
          <Facets>
            <Facet Name="System Name">
              <String Value="Global Ocean Observing System (GOOS) Global Sea Level Observing System" />
            </Facet>
            <Facet Name="Acronym">
              <String Value="GOOS GLOSS" />
            </Facet>
            <Facet Name="Owner">
              <String Value="Networks" />
              <String Value="Foreign" />
              <String Value="NOAA" />
            </Facet>
            <Facet Name="Line Office">
              <String Value="Climate Goal" />
            </Facet>
            <Facet Name="Type">
              <String Value="Ocean-Fixed" />
            </Facet>
            <Facet Name="Point of Contact">
              <String Value="Clark, Candyce" />
            </Facet>
            <Facet Name="Intended Use">
              <String Value="Research" />
            </Facet>
            <Facet Name="Lifecycle Phase">
              <String Value="Operations" />
            </Facet>
            <Facet Name="Environmental Parameter">
              <String Value="Sea Level" />
              <String Value="Sea Surface Height" />
              <String Value="Water Level" />
            </Facet>
            <Facet Name="System Webpage">
              <Link Name="http://ilikai.soest.hawaii.edu/" Href="http://ilikai.soest.hawaii.edu/" />
            </Facet>
          </Facets>
        </Item>

    Its interesting because if I did item["Href"][0] it would give me the first Href in the Item's tag. But them if I did ["Href"][1] I thought it would give me the next since there is another Href, but nothing comes up, the adnorner doesn't even show up.

    Monday, March 19, 2012 12:36 PM
  • I think I see the over  arching issue now.

    Because when I tested item["System Name"] and any other that just has a String value it works.

    But my System Webpage has more than two properties

            <Facet Name="System Webpage">
              <Link Name="http://ilikai.soest.hawaii.edu/" Href="http://ilikai.soest.hawaii.edu/" />
            </Facet>

    So I think when I do item["System Webpage"][0], it doesn't return anything because [0] it doesn't have the value it probably has some other structure behind it. How do I view this structure? There has to be a better way to troubleshoot this.

    Monday, March 19, 2012 2:15 PM
  • Ah looked like I just had to cast it as a PivotViewerHyperlink to get the values I need!

    Monday, March 19, 2012 4:09 PM
  • I guess one can't have a Facet named Description or Href (or maybe Img too)
    Tuesday, August 27, 2013 10:24 PM
  • Thanks to your digging into this, I have this item adorner command now at http://gallery.clipflair.net/activity and http://gallery.clipflair.net/video, note
    { return item["Name"][0] + " - " + item["Description"][0]; } below at ToolTip property.

    However have still to figure out how to make PivotViewer load images from inside a component DLL hosted in the XAP file (maybe use a package URL instead?) and to figure out how to show/hide the details pane of pivotviewer programmatically

    //Project: ClipFlair (http://ClipFlair.codeplex.com)
    //Filename: InfoCommand.cs
    //Version: 20130828

    using System.Windows.Controls.Pivot;

    namespace ClipFlair.Windows.Gallery.Commands
    {

      public class InfoCommand : IPivotViewerUICommand
      {
        PivotViewerItem item;

        public InfoCommand(PivotViewerItem theItem)
        {
          item = theItem;
        }

        public string DisplayName
        {
          get { return "(i)"; }
        }

        public System.Uri Icon
        {
          get { return null; /* new System.Uri("/ClipFlair.Windows.Gallery;component/Images/Info.png"); */}
        }

        public object ToolTip
        {
          get { return item["Name"][0] + " - " + item["Description"][0]; }
        }

        public bool CanExecute(object parameter)
        {
          return true;
        }

        public event System.EventHandler CanExecuteChanged;

        public void Execute(object parameter)
        {
          //TODO
        }

      }

    }

    Note that I setup actions like below:

        

    privatevoid GalleryItemAdorner_CommandsRequested(object sender, PivotViewerCommandsRequestedEventArgs e)     {       //if (e.IsItemSelected)       {         e.Commands.Add(newInfoCommand((PivotViewerItem)e.Item));         //e.Commands.Add(new ShareCommand());//e.Commands.Add(new DownloadCommand());//e.Commands.Add(new OpenCommand());       }     }

    I pass the item to the InfoCommand at constructor, since I want to access it from the Tooltip property, not just from thje Execute method of the command

                        
    • Edited by ClipFlair Tuesday, August 27, 2013 10:54 PM
    Tuesday, August 27, 2013 10:49 PM
  • Found out what the issue was with the adorner not showing an image of embedded resource build type (in a DLL inside the XAP that is), had to use UriKind.Relative when constructing the URL I return from the command implementation

    Also, noticed that if description is missing, then item["Description"] seems to return an empty IList, not null as I expected. See "makeTooltip" below how complex it got to get Name and Description and combine them in a string (string.IsEmpty there is just an extension method that checks if trim() returns string with length 0)

    //Project: ClipFlair (http://ClipFlair.codeplex.com)
    //Filename: InfoCommand.cs
    //Version: 20130828
     
    using Utils.Extensions;
    using System;
    using System.Collections;
    using System.Windows.Controls.Pivot;
     
    namespace ClipFlair.Windows.Gallery.Commands
    {
     
      public class InfoCommand : BaseCommand
      {
     
        public InfoCommand(PivotViewerItem item) : base()
        {
          Icon = new System.Uri("/ClipFlair.Windows.Gallery;component/Images/Info.png"UriKind.Relative); //must specify that this is a relative Uri
          ToolTip = makeTooltip(item);
          IsExecutable = true//needed to show the tooltip
        }
     
        protected string makeTooltip(PivotViewerItem item)
        {
          IList nameData = item["Name"];
          string name = (nameData != null && nameData.Count > 0)? (string)nameData[0] : "";
          if (name == null)
            name = ""//just to be safe
     
          IList descriptionData = item["Description"];
          string description = (descriptionData != null && descriptionData.Count > 0) ? (string)descriptionData[0] : "";
          if (description == null)
            description = ""//just to be safe
          
          return name +
                 ((name.IsEmpty() || description.IsEmpty())? "" : "\n\n") + 
                 description;
        }
     
        public override void Execute(object parameter)
        {
          base.Execute(parameter);
          //TODO: toggle visibility of Details pane (may need to pass pivot viewer itself at constructor or a reference to the details pane)
        }
     
      }
     
    }
    


    Microsoft MVP J# 2004-2010, Borland Spirit of Delphi 2001

    Wednesday, August 28, 2013 3:15 PM