The setup
So I have a class, ComputerItem, designed to store everything I need to know about a specific computer; these items are stored in an ObservableCollection<ComputerItem>. I then have a custom control ComputerControl, which has (among other things) a few text boxes bound to members of ComputerItem, the bindings made available like so:
<TextBlock Name="tb_computerName"TextWrapping="Wrap" Text="{Binding ElementName=ComputerControl1, Path=computerName}"/>
and in the code behind
public static DependencyProperty computerNameProperty = DependencyProperty.Register("computerName", typeof(string), typeof(ComputerControl), null);
I then create a MultiselectList of ComputerControl objects:
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<toolkit:MultiselectList x:Name="lb_computers" IsSelectionEnabledChanged="lb_computers_IsSelectionEnabledChanged"> <!--SelectionChanged="lb_computers_SelectionChanged" >-->
<toolkit:MultiselectList.ItemTemplate>
<DataTemplate>
<StackPanel x:Name="sp">
<local:ComputerControl computerName="{Binding Name}" MACAddress="{Binding DisplayMAC}" playClicked="playClicked_Handler" editClicked="editClicked_Handler"/>
</StackPanel>
</DataTemplate>
</toolkit:MultiselectList.ItemTemplate>
</toolkit:MultiselectList>
</Grid>
and you can see the data bindings in the ComputerControl definition. In the code behind I bind the ObservableCollection to the MultiselectList:
this.lb_computers.ItemsSource = ComputerListMaintainer.GetList();
and all of this (as well as a few things I’m sure I’ve forgotten to include here) works beautifully to fill the MultiselectList with ComputerControls representing the ComputerItems in the ObservableCollection.
The problem
My issue is that when the underlying ComputerItem changes, the TextBlocks in the corresponding ComputerControl don’t update. I’ve implemented INotifyPropertyChanged in the ComputerItem class:
public class ComputerItem : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private string name;
protected virtual void OnPropertyChanged(string name)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(name));
}
public string Name
{
get { return name; }
set { OnPropertyChanged("Name"); name = value; }
}
}
but that didn’t solve the problem. I suspect it’s something to do with ComputerControl but I have no idea where to start looking; the closest question I’ve found suggested INotifyPropertyChanged should have been the solution but they weren’t using a custom control in that case, just a custom class, if I remember correctly.
What am I missing?
Well your setter is incorrect for starters; also do look into MvvmLight, as it provides a great API for this kind of plumbing work.
Update:
You shouldn’t be setting lb_computers.ItemsSource in your code behind, because that’s one time operation and not a binding. It is better to bind to an ObservableCollection of observable objects (aka INotifyPropertyChanged).
Also I’m not sure if you’re properly declaring your dependency property, so below you can find a proper setup on how to define a ‘bindable’ property.
And also with XAML, the architecture of your code matters, to have a sane experience. I highly recommend that you utilize the Mvvm pattern. I find MvvmLight and MEFedMVVM to be great aids in my development. This require a bit of work at the beginning, but it’ll be far easier to debug future issues and maintain your code.
If these tips don’t help, then I’d have to see your full code.
Declaring a Bindable Property