• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 473
  • Last Modified:

Data Template in wpf

Hi,

Im trying to create a custom control in wpf which will be used to display a list of custom objects

i have a list of these objects in my user control class called penalties.

the following code is on the xaml:

<ListBox ItemsSource="{Binding Penalties}" Grid.RowSpan="2" Grid.Row="2" Name="lstTest">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <StackPanel Orientation="Horizontal">
                        <TextBlock FontWeight="Bold" Text="{Binding Team}" />
                        <TextBlock Text=" - " />
                        <TextBlock Text="{Binding TimeLeft}" />
                    </StackPanel>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>

Open in new window


and the following is in the c#

private List<IceHockeyPenalty> penalties = null;

        public List<IceHockeyPenalty> Penalties
        {
            get { return penalties; }
            set { penalties = value; }
        }

        public PenaltyInfoControl()
        {
            InitializeComponent();
            this.penalties = new List<IceHockeyPenalty>();
            base.DataContext = penalties;
            lstTest.ItemsSource = penalties;
        }

        public void addPenaltyInfo(IceHockeyPenalty penaltyInfo)
        {
            penalties.Add(penaltyInfo);
        }

Open in new window


but nothing appears in the list when i add a new penalty

I've tried different variations of the above but no luck, can somebody tell me what i'm missing?

Thanks
0
basil365
Asked:
basil365
  • 3
  • 3
2 Solutions
 
vbighamCommented:
Instead of List<IceHockeyPenalty>, try using ObservableCollection<IceHockeyPenalty>.

That type of collection will report when its items have changed, and update the list box accordingly.

http://msdn.microsoft.com/en-us/library/ms668604.aspx
0
 
jagrut_patelCommented:
Try this.

private List<IceHockeyPenalty> penalties = null;

public PenaltyInfoControl()
{
  InitializeComponent();
  this.penalties = new List<IceHockeyPenalty>();
  this.DataContext = new { Penalties = penalties };
}

Open in new window


<ListBox ItemsSource="{Binding Penalties}" Grid.RowSpan="2" Grid.Row="2" Name="lstTest">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <StackPanel Orientation="Horizontal">
                        <TextBlock FontWeight="Bold" Text="{Binding Team}" />
                        <TextBlock Text=" - " />
                        <TextBlock Text="{Binding TimeLeft}" />
                    </StackPanel>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox> 

Open in new window


Items in List<T> will be shown in the control once when the databinding happens. Any additions to the List<T> at run-time won't be reflected into the control. If your need is to add items to ListBox at run-time then as @vbigham mentioned you can change to ObservableCollection<T> instead of List<T>.
0
 
basil365Author Commented:
Thanks to you both, that works for the 'team' attribute on the icehockeypenalty object - it displays in the listbox correctly.

The 'timeLeft' attribute is slightly different in that in gets updated internally by a timer. The attribute itself is simply a string also, but no value gets printed on my data template.

this is the iceHockeyPenalty class:
public class IceHockeyPenalty
    {
        TimeSpan penaltyTime;
        DispatcherTimer timer;
        TimeSpan timerInterval = new TimeSpan(0, 0, 1);
        bool isValidPenalty;
        string team;
        string timeLeft;

        public string TimeLeft
        {
          get { return timeLeft; }
        }

        public string Team
        {
            get { return team; }
        }

        public IceHockeyPenalty(TimeSpan penaltyTime,string team)
        {
            this.team = team;
            this.penaltyTime = penaltyTime;
            timer = new DispatcherTimer();
            timer.Interval = timerInterval;
            timer.Tick += new EventHandler(timer_Tick);
            timer.Start();
            isValidPenalty = true;
        }

        void timer_Tick(object sender, EventArgs e)
        {
            //reduce the penalty time left
            penaltyTime = penaltyTime.Subtract(timerInterval);

            //make sure this peno is not counted if its not valid
            if (penaltyTime <= new TimeSpan(0, 0, 0))
                isValidPenalty = false;

            timeLeft = penaltyTime.Minutes + ":" + penaltyTime.Seconds;
        }

        public void extendPenalty(int minutes)
        {
            this.penaltyTime.Add(new TimeSpan(0,minutes,0));
        }

    }

Open in new window

0
Introducing Cloud Class® training courses

Tech changes fast. You can learn faster. That’s why we’re bringing professional training courses to Experts Exchange. With a subscription, you can access all the Cloud Class® courses to expand your education, prep for certifications, and get top-notch instructions.

 
jagrut_patelCommented:
Did you changed to ObservableCollection?
0
 
basil365Author Commented:
I did, that seems to just update if the collection changes - not if the internal objects of that collection change?

I'm looking at IObserver<T> at the moment but its current out of my grasp
0
 
jagrut_patelCommented:
You're right. Your object "IceHockeyPenalty" needs to implement INotifyPropertyChanged.
See this example.
0
 
basil365Author Commented:
thanks very much
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

Free Tool: SSL Checker

Scans your site and returns information about your SSL implementation and certificate. Helpful for debugging and validating your SSL configuration.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

  • 3
  • 3
Tackle projects and never again get stuck behind a technical roadblock.
Join Now