Question

This is my first time posting a question. I'm looking into this issue for about a whole day but cannot see why this binding doesn't work.

I want a Label to display the name of a object "hotspot" which is a Property of class instance named Plan. There are multiple plans and each plan contains multiple hotspots. When I click on a hotspot the property Plan.SelectedHotSpot sets this clicked hotspot as value. If there is no HotSpot selected it turns to null.

XAML:

<Label Name="lblHotSpotName" />

MainWindow code behind when Plan is selected from ListBox:

private void lstPlans_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    canvas.Plan = PlanBLL.GetPlanByID(plans[lstPlans.SelectedIndex].ID);
    lblHotSpotName.DataContext = canvas.Plan;
    lblHotSpotName.SetBinding(Label.ContentProperty, "SelectedHotSpot.Name");
}

Plan class:

public class Plan : INotifyPropertyChanged
{
    private HotSpot selectedHotSpot;

    public HotSpot SelectedHotSpot
    {
        get { return selectedHotSpot; }

        set
        {
            selectedHotSpot = value;
            OnPropertyChanged("SelectedHotSpot");
            OnPropertyChanged("SelectedHotSpot.Name");
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    void OnPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
 }

This code doesn't seem to work when I click on a hotspot lblHotSpotName stays empty. It seems to me that when a plan is loaded SelectedHotSpot is null and so it doesn't bind to that hotspot object which is selected after the plan has been loaded. Is my insinuation right? That this binding needs to have an existing object which is not null. And when the object changes that we need to define the binding from label to Plan.SelectedHotSpot again.

Thanks for your help.

Was it helpful?

Solution

I can't be sure that I have understood your problem exactly right because your question is somewhat unclear, but can you not just data bind to the Label.Content property in XAML? If you want to data bind the SelectedHotSpot.Name property of the Plan item that is currently selected in the ListBox, then you should be able to do something like this:

<Label Name="lblHotSpotName" 
   Content="{Binding SelectedItem.SelectedHotSpot.Name, ElementName=lstPlans}" />

UPDATE >>>

You're still better off using XAML for your Binding. Add a string property to bind to and then update that in your lstPlans_SelectionChanged handler instead:

<Label Name="lblHotSpotName" Content="{Binding SelectedItemHotSpotName}" />

...

private void lstPlans_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    canvas.Plan = PlanBLL.GetPlanByID(plans[lstPlans.SelectedIndex].ID);
    SelectedItemHotSpotName = canvas.Plan.SelectedHotSpot.Name;
}

OTHER TIPS

I'm not sure it will help or not, but in lstPlans_SelectionChanged try this Binding:

var myBinding = new Binding();

myBinding.Path = new PropertyPath("SelectedHotSpot.Name");
myBinding.Source = canvas.Plan;
lblHotSpotName.SetBinding(Label.ContentProperty, myBinding);

If SelectedHotSpot.Name doesn't change, when this line is not needed:

OnPropertyChanged("SelectedHotSpot.Name");

in SelectedHotSpot property declaration.

Don't see any issue in the given code (though, Raise property changed for .Name is not required).

I would suggest to confirm that selectedHotSpot always has some instance and is not null. Try modifying your plan class and set:

selectedHotSpot = new HotSpot(Name="Default")

and you should see "Default" in your label.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top