Saturday, September 1, 2012

Access ListBoxItem in codebehind

Access ListBoxItem in codebehind

Hello friends,

I am working with a Silverlight Chat application.I am binding the messages to the Listbox from codebehind.

Now I want to give different style to ListBoxItem .This style will depend on the message owner,, like if the message is sent by current user then want to give style1 and if the message is recieved by user then I want to give style2.

I tried lot to search it on google, but still not able to implement this.

Summary : How can i bind style to ListBoxItem from code behind when binding the datasource to ListBox.

Thanks in advance

Answers & Comments...

Answer: 1

vijay_sutaria

Summary : How can i bind style to ListBoxItem from code behind when binding the datasource to ListBox.

I have a sample code for you, i hope this will help you, let me know if you still have nay doubts.

<UserControl x:Class="SilverlightApplication3.MainPage"      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"      xmlns:d="http://schemas.microsoft.com/expression/blend/2008"      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"      mc:Ignorable="d"      d:DesignHeight="300" d:DesignWidth="400">        <Grid x:Name="LayoutRoot" Background="White">          <ListBox x:Name="LstBx">              <ListBox.ItemTemplate>                  <DataTemplate>                      <StackPanel Background="{Binding Path=BackColor}" >                          <TextBlock Text="{Binding Path=Text, Mode=TwoWay}" FontSize="20" FontWeight="Bold"></TextBlock>                      </StackPanel>                  </DataTemplate>              </ListBox.ItemTemplate>          </ListBox>      </Grid>  </UserControl>        using System;  using System.Collections.Generic;  using System.Linq;  using System.Net;  using System.Windows;  using System.Windows.Controls;  using System.Windows.Documents;  using System.Windows.Input;  using System.Windows.Media;  using System.Windows.Media.Animation;  using System.Windows.Shapes;    namespace SilverlightApplication3  {      public partial class MainPage : UserControl      {          public MainPage()          {              InitializeComponent();              this.Loaded += new RoutedEventHandler(MainPage_Loaded);          }            void MainPage_Loaded(object sender, RoutedEventArgs e)          {              var chats = new List<Chat>();                chats.Add(new Chat                          {                              Text = "hi",                              BackColor = new SolidColorBrush(Colors.Blue)                          });                chats.Add(new Chat                          {                              Text = "hello",                              BackColor = new SolidColorBrush(Colors.Brown)                          });                chats.Add(new Chat                          {                              Text = "bye",                              BackColor = new SolidColorBrush(Colors.Green)                          });              LstBx.ItemsSource = chats;          }      }        public class Chat      {          public string Text { get; set; }          public SolidColorBrush BackColor{get;set;}      }  }    





Answer: 2

Hi syed amjad,

Thanks for your reply.

the solution which you have given in your reply is one of the best possible solution.

But my issue is , I dont have to set only backgroud property, so my designer have created 2 different style , which I have to apply to my ListBoxItems, and if suppose I will try by the way you shown above then I will have to declare to many properties for the styles.

I hope you are getting me.

So, Please guide me here. Or else any other way which can help me to achieve this.

Thanks Again



Answer: 3

Hi Vijay,

I can think of a number of ways to do this.  I would suggest that getting access to the ListBoxItem in code behind is not really a good idea and would caution you against it.  It's just hacky...

1. If you have access to Telerik's products, you can use their listbox which has a ItemContainerStyleSelector and ItemTemplateSelector.  Your scenario is exactly what they are intended for....  Choosing a style or a template based on some property of the data context object.

2.  You could create your own DataTemplateSelector like this: http://forums.silverlight.net/t/182504.aspx
You would define a listboxitem with the two styles and pick which one to apply based on your message type (incoming/outgoing)

3. You could create a customcontrol which you place inside the listboxitemtemplate.  The custom control would have bindable properties like style, and whatever else you'd need, and you can bind those properties to the datacontext object.

IMHO - even though these are more complex, they will provide you with a much better starting point for extending your code later and separating the business logic from the visuals...

If you have trouble with any of these, let me know and I can probably provide some samples.



Answer: 4

Hello friends,

Thanks for your replies.

finally I got the solution and so I am able to assign style to ListBoxItem based on some condition in codebehind.

What I found is :

Whenever I will bind ItemSource property of ListBox, Its SelectionChanged event is executing.

I have written below code to access all the ListBoxItem, and then have applied the style from the theme file.

void listBox_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)
        {
            var stacks = GetChilds(listBox).OfType<System.Windows.Controls.ListBoxItem>();
            ResourceDictionary mystyles = new ResourceDictionary();
            mystyles.Source = new Uri("/ChatApp;component/Assets/Themes/Theme1.xaml", UriKind.RelativeOrAbsolute);
            foreach (System.Windows.Controls.ListBoxItem o in stacks)
            {
                if (((MyModels.Message)(o.Content)).SourceGroup.ID == Convert.ToString((int)this.sourceGroup))
                    o.Style = mystyles["ListBoxItemStyle1"] as Style;
                else
                    o.Style = mystyles["ListBoxItemStyle2"] as Style;

            }
            listBox.UpdateLayout();
        }


        private static IEnumerable<DependencyObject> GetChilds(DependencyObject root)
        {
            List<DependencyObject> lst = new List<DependencyObject>();
            lst.Add(root);
            for (int i = 0; i < VisualTreeHelper.GetChildrenCount(root); i++)
                lst.AddRange(GetChilds(VisualTreeHelper.GetChild(root, i)));

            return lst;
        }

So using above code I am able to assign the style to each listitem based on any condition in CodeBehind just after assigning the ItemSource property.

I dont know whether this is the perfect solution or not, but I am able to achieve the functionality which I have to implement.

Might be helpful to others.

thank you very much for your support friends.





No comments:

Post a Comment

Send us your comment related to the topic mentioned on the blog