Powered by MSDN

US - English
NEW! Silverlight 5 is available Learn More

Changing Item Properties on a Databound ListBox RSS

5 replies

Last post Jan 14, 2009 05:38 PM by ihilder

(0)
  • ihilder

    ihilder

    Member

    4 Points

    8 Posts

    Changing Item Properties on a Databound ListBox

    Jan 12, 2009 05:35 PM | LINK

    Hey guys,

    I'm doing some tweaks to my current project and seem to be missing something when it comes to changing properties on a databound item.  I'm pulling some feed stories from XML w/ Linq and then binding them to a formatted Listbox for display.  The information itself is being bound to a HyperlinkButton which I need the ability to change the opacity and fontsize programmatically on after an animation event completes.  When I pull the Item at SelectedIndex it is returning my object that I'm binding to the Listbox, rather than the elements, like the HyperlinkButton, contained within that ListBox.  Am I missing something?  If not how do I get to said HyperlinkButton.  Here's a XAML snippet for the Listbox I'm trying to pull from.  Let me know if any more info is needed.  Thanks in advance.

    XAML:

    <ListBox x:Name="FeedBox" BorderThickness="0,0,0,0"  ItemContainerStyle="{StaticResource styleListBoxItem}">
              <ListBox.ItemTemplate>
                       <DataTemplate>
                                    <HyperlinkButton Opacity=".5" Background="Transparent" Content="{Binding TrimmedTitle}" NavigateUri="{Binding LinkUri}"      MouseEnter="onItemMouseOver" MouseLeave="onItemMouseOut" TargetName="_blank" FontSize="13" FontFamily="./RotisSemiSans.otf#RotisSemiSans" Foreground="#FF8E8E8E"/>
                        </DataTemplate>
              </ListBox.ItemTemplate>
      </ListBox>

  • anyeone

    anyeone

    Participant

    826 Points

    199 Posts

    Re: Changing Item Properties on a Databound ListBox

    Jan 12, 2009 07:03 PM | LINK

     Is there a reason you can't bind the opacity and font size properties through the XAML to some helper property of the bound object that you modify from the code when your animation completes?  If you are going to set the opacity and font size directly these could be simply called Opacity and FontSize, but if you need to calculate these values based on some other property you could name them something else and use a IValueConverter to determine the opacity & font size based on another property.

    So after your animation completes you would do...

    YourObjectType selectedObj = FeedBox.SelectedItem as YourObjectType;

    if (selectedObj !=null)

    {

        selectedObj.PropertyThatControlsOpacity = ...;

        selectedObj.PropertyThatControlsFontSize = ...;

    }

    (I always forget some details in the first post...edited to add..)

    Your xaml then would contain Opacity="{Binding PropertyThatControlsOpacity}" FontSize="{Binding PropertyThatControlsFontSize}"

    and you'd programmatically initialize these to 0.5 and 13 respectively when you first load the object.  If your post-animation code needs to calculate based on some other property, you could write a converter class OpacityConverter that implements IValueConverter, then in your xaml for the hyperlink you'd instead have:  Opacity="{Binding Path=PropertyThatControlsOpacity,Converter={StaticResource opacityConverter}}" etc.  and a declaration at the top of your xaml:  <yournamespace:OpacityConverter x:Name="opacityConverter" />.  There are tons of examples of how to implement these online if you haven't done one yet.

    What I'm not sure of is whether this binding would conflict with animation code that explicitly sets the opacity and font size, since I've not actually tried this method in conjunction with animations.   It's worth trying though if you haven't yet, since it's a fairly simple (and common xaml) solution if it works.

    --
    Anye Mercy
    AnyeDotNet.blogspot.com

    Please "Mark as Answer" the posts that help you - this lets others know the problem has been solved and helps others having the same problem know which solution works. Thanks!
  • ihilder

    ihilder

    Member

    4 Points

    8 Posts

    Re: Changing Item Properties on a Databound ListBox

    Jan 12, 2009 09:42 PM | LINK

     So your recommendation half worked.  For some reason it will allow me to change the Opacity initally when the ListBox is populated, but if I try to change it programmatically when the animation is completed it doesn't work.  In debug it shows that its setting the SelectedItem's opacity correctly, but it's visually not changing.  Any ideas? 

    XAML:

    <ListBox x:Name="FeedBox" BorderThickness="0,0,0,0"  ItemContainerStyle="{StaticResource styleListBoxItem}">
              <ListBox.ItemTemplate>
                           <DataTemplate>
                                     <HyperlinkButton Opacity="{Binding OpacityHelper}" Background="Transparent" Content="{Binding TrimmedTitle}" NavigateUri="{Binding LinkUri}" MouseEnter="onItemMouseOver" MouseLeave="onItemMouseOut" TargetName="_blank" FontSize="13" FontFamily="./RotisSemiSans.otf#RotisSemiSans" Foreground="#FF8E8E8E"/>
                            </DataTemplate>
                 </ListBox.ItemTemplate>
     </ListBox>

    Code Behind:

     Initial ListBox setup:

       private void DisplayFeed()
            {
                //Creates a stream of the xml file for debugging
                Stream stream = this.GetType().Assembly.GetManifestResourceStream("project.feed.xml");

                //Loads stream into a local xml Document
                XDocument xmlStudies = XDocument.Load(new StreamReader(stream));


                var stories = from story in xmlStudies.Descendants("item")
                              select new Story
                              {
                                  Title = (string)story.Element("title"),
                                  LinkUri = (string)story.Element("link"),
                                  OpacityHelper = 0.5,
                              };

                //Some code...
               
                FeedBox.ItemsSource = stories;
                FeedBox.SelectedIndex = 0;

          
                FeedAnimation.Begin();
                FeedAnimation.Completed += new EventHandler(FeedAnimation_Completed);

                Story start = FeedBox.SelectedItem as Story;
                start.OpacityHelper = 1;
                FeedBox.SelectedItem = start;
            }

      void FeedAnimation_Completed(object sender, EventArgs e)
            {
               Story tempStory = FeedBox.SelectedItem as Story;
                tempStory.OpacityHelper = 0.5;
                FeedBox.SelectedItem = tempStory;
               
                if (Number of Feed Stories > (FeedBox.SelectedIndex + 1))
                {               
                    FeedBox.SelectedIndex++;

                    tempStory = FeedBox.SelectedItem as Story;
                    tempStory.OpacityHelper = 1;
                    FeedBox.SelectedItem = tempStory;

                    FeedAnimation.Begin();
                }

    Story Object:

      public class Story
        {
            public string Title         { get; set; }
            public string LinkUri       { get; set; }
            public string TrimmedTitle  { get; set; }

            public double OpacityHelper { get; set; }
            public int FontSizeHelper   { get; set; }
      

            TrimmedTitle Helper Method()

        }

  • anyeone

    anyeone

    Participant

    826 Points

    199 Posts

    Re: Re: Changing Item Properties on a Databound ListBox

    Jan 12, 2009 10:03 PM | LINK

     Story needs to implement INotifyPropertyChanged in order for the binding to work.  This is the interface that XAML based apps use to automatically notify the UI of changes to the underlying properties.   Sorry I didn't mention it in my last post, I assumed since you already were binding objects in XAML that your business object would implement it already. 

    After you implement it (creating the PropertyChanged event), create a helper method in story as:

    private void NotifyPropertyChanged(string propname)

    {

      if (PropertyChanged!=null)

    {

        PropertyChanged(this, new PropertyChangedEventArgs(propname));

    }

    }

    Then in your OpacityHelper and FontSizeHelper properties:

    private double _OpacityHelper;

    public double OpacityHelper {

    get { return _OpacityHelper;}

    set { _OpacityHelper=value; NotifyPropertyChanged("OpacityHelper");}

    } etc.

     

    --
    Anye Mercy
    AnyeDotNet.blogspot.com

    Please "Mark as Answer" the posts that help you - this lets others know the problem has been solved and helps others having the same problem know which solution works. Thanks!
  • ihilder

    ihilder

    Member

    4 Points

    8 Posts

    Re: Re: Changing Item Properties on a Databound ListBox

    Jan 13, 2009 12:23 AM | LINK

    Perfect!  Thanks for the help.
  • ihilder

    ihilder

    Member

    4 Points

    8 Posts

    Re: Re: Changing Item Properties on a Databound ListBox

    Jan 14, 2009 05:38 PM | LINK

    Secondary question...

    How would I go about grabbing ActualWidth of the HyperlinkButton?   I need to resize a container box based on the ActualWidth of a formatted Title.