0

I have done the following in XAML

<ItemsControl x:Name="CursorLegendIC" Grid.Column="0" Grid.Row="1" ItemsSource="{Binding}" Margin="0,0" Padding="0,0,0,-300">
                <ItemsControl.ItemTemplate>
                    <DataTemplate>
                        <StackPanel Orientation="Vertical">
                            <Ellipse Width="8" Height="8" HorizontalAlignment="Left" Margin="0,0,0,-16" Fill="{Binding SeriesColor, Converter={StaticResource ColorToBrushConverter}}" />
                            <TextBlock Margin="10,0,0,0" HorizontalAlignment="Left" TextWrapping="Wrap" FontSize="11" FontWeight="Bold" Foreground="{Binding SeriesColor, Converter={StaticResource ColorToBrushConverter}}" Text="{Binding SeriesName}"/>
                            <TextBlock FontSize="11" HorizontalAlignment="Left" TextWrapping="Wrap" Margin="10,-3,0,4" Foreground="{Binding SeriesColor, Converter={StaticResource ColorToBrushConverter}}" Text="{Binding YValue, StringFormat=\{0:0.000\}}" />
                            <TextBlock FontSize="11" HorizontalAlignment="Left" TextWrapping="Wrap" Margin="10,-8,0,4" Foreground="{Binding SeriesColor, Converter={StaticResource ColorToBrushConverter}}" Text="{Binding RenderableSeries.YAxisId}"/>
                        </StackPanel>
                    </DataTemplate>                        
                </ItemsControl.ItemTemplate>                    
            </ItemsControl>      

And I have set the data context accordingly:

void MainPage_Loaded(object sender, RoutedEventArgs e)
    {

        CursorLegendIC.DataContext = this.RolloverSeriesWithoutFirstData;
    }

And set the Observable collection property as public

public ObservableCollection<SeriesInfo> RolloverSeriesWithoutFirstData
    {
        get
        {
            ObservableCollection<SeriesInfo> Temp = rolloverModifier.SeriesData.SeriesInfo;
            return Temp;
        }
    }

But binding is still not working!

It seems to only take the binding at the first instance.

When data collection is later added, the binding changes does not seem to take effect.

Any help? Thanks

user1034912
  • 2,153
  • 7
  • 38
  • 60
  • My guess is either, you are updating the collection asynchronously, which `INotifyCollectionChanged` does not support, or you are replacing the instance value of the property `RolloverSeriesWithoutFirstData`, without telling the binding that the value has changed (Implement `INotifyPropertyChanged` and raise the event inside the set method) – Anders Mar 20 '15 at 07:19
  • If you update async you can either to this if on .NET 4.5 or higher: [How do I update an ObservableCollection via a worker thread?](http://stackoverflow.com/a/14602121/1548864) or this if below [AsyncObservableCollection](https://gist.github.com/thomaslevesque/10023516) (NOTE: instance of the collection must be created on the UI thread) – Anders Mar 20 '15 at 07:22
  • Sorry.. Did not see you had a get only on the property.. Do you change the instance of `rolloverModifier.SeriesData.SeriesInfo`, or does it remain the same? – Anders Mar 20 '15 at 07:27
  • *"It seems to only take the binding at the first instance"*. Yes it is, unless you raise property changed notification which will tell binding to refresh it's value : [How to: Implement the INotifyPropertyChanged Interface](https://msdn.microsoft.com/en-us/library/vstudio/ms229614%28v=vs.100%29.aspx) – har07 Mar 20 '15 at 07:49
  • hi Nautious, yes the 'rolloverModifier.SeriesData.SeriesInfo' does changes – user1034912 Mar 20 '15 at 23:51
  • Funny i just noticed that only whenI inspect the data during debug, will the data change – user1034912 Mar 21 '15 at 00:07
  • 1
    Okay.. It's because `SeriesInfo` changes, but the owner of `RolloverSeriesWithoutFirstData` is not notified of this change. You need an event in `SeriesData` which tells the owner of `RolloverSeriesWithoutFirstData` that `SeriesInfo` has changed. Then the owner of `RolloverSeriesWithoutFirstData` need to implement `INotifyPropertyChanged` to tell the binding that the `RolloverSeriesWithoutFirstData` has changed. Then ItemsSource will update. – Anders Mar 21 '15 at 10:48
  • 1
    I've posted an answer that takes care of your problem. – Anders Mar 21 '15 at 11:07

4 Answers4

1

Your issue is that the instance (the entire collection) of the property SeriesInfo changes, without the owner of RolloverSeriesWithoutFirstData (lets call it MyWindow) is notified of the change. Either make your own event, or implemenet INotifyPropertyChanged. I've made an example with INPC:

class SeriesData : INotifyPropertyChanged
{
    private ObservableCollection<SeriesInfo> _seriesInfo;
    public ObservableCollection<SeriesInfo> SeriesInfo
    {
        set{ SetProperty(ref _seriesInfo, value); }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    private bool SetProperty<T>(ref T storage, T value, [CallermemberName] string propertyName = null)
    {
        if(Equals(storage,value)) return false;
        storage = value;

        var handler = PropertyChanged;
        if(handler != null)
            handler(this, new PropertyChangedEventArgs(propertyName));
        return true;
    }
}

In MyWindow you does this:

class MyWindow : Window, INotifyPropertyChanged
{
    public ObservableCollection<SeriesInfo> RolloverSeriesWithoutFirstData
    {
        get{ return rolloverModifier.SeriesData.SeriesInfo; }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    public MyWindow()
    {
        // Get rolloverModifier
        rolloverModifier.SeriesData.PropertyChanged += SeriesDataPropertyChanged;
    }

    private void SeriesDataPropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        switch(e.PropertyName)
        {
            case "SeriesInfo":
                RaisePropertyChanged("RolloverSeriesWithoutFirstData");
                break;
        }
    }

    private void RaisePropertyChanged([CallerMemberName] string propertyName = null)
    {
        var handler = PropertyChanged;
        if(handler != null)
            handler(this, new PropertyChangedEventArgs(propertyName));
    }

Now SeriesData notifies it's listeners (our case MyWindow) that one of it's properties has changed value. MyWindow will then relay that notification to it's listeners (the bindings) that it's property: RolloverSeriesWithoutFirstData has changed.

Anders
  • 1,590
  • 1
  • 20
  • 37
0

Assuming that you are using MVVM pattern, you should remove the code behind and just bind to your ObservableCollection :

<ItemsControl x:Name="CursorLegendIC" Grid.Column="0" Grid.Row="1" ItemsSource="{Binding RolloverSeriesWithoutFirstData}" Margin="0,0" Padding="0,0,0,-300">
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <StackPanel Orientation="Vertical">
                        <Ellipse Width="8" Height="8" HorizontalAlignment="Left" Margin="0,0,0,-16" Fill="{Binding SeriesColor, Converter={StaticResource ColorToBrushConverter}}" />
                        <TextBlock Margin="10,0,0,0" HorizontalAlignment="Left" TextWrapping="Wrap" FontSize="11" FontWeight="Bold" Foreground="{Binding SeriesColor, Converter={StaticResource ColorToBrushConverter}}" Text="{Binding SeriesName}"/>
                        <TextBlock FontSize="11" HorizontalAlignment="Left" TextWrapping="Wrap" Margin="10,-3,0,4" Foreground="{Binding SeriesColor, Converter={StaticResource ColorToBrushConverter}}" Text="{Binding YValue, StringFormat=\{0:0.000\}}" />
                        <TextBlock FontSize="11" HorizontalAlignment="Left" TextWrapping="Wrap" Margin="10,-8,0,4" Foreground="{Binding SeriesColor, Converter={StaticResource ColorToBrushConverter}}" Text="{Binding RenderableSeries.YAxisId}"/>
                    </StackPanel>
                </DataTemplate>                        
            </ItemsControl.ItemTemplate>                    
        </ItemsControl>  

+Questions: what is rolloverModifier ? is rolloverModifier.SeriesData.SeriesInfo modified?

Dragos Stoica
  • 1,753
  • 1
  • 21
  • 42
0

You just need to implement the INotifyPropertyChanged Interface in the class that you defined your RolloverSeriesWithoutFirstData property in. As that property has no setter, you will have to manually raise the NotifyPropertyChanged event whenever you update the collection:

(pseudo code):

rolloverModifier.SeriesData.SeriesInfo = DataAccess.GetNewCollection();
NotifyPropertyChanged("RolloverSeriesWithoutFirstData");
Sheridan
  • 68,826
  • 24
  • 143
  • 183
-2

Change

CursorLegendIC.DataContext = this.RolloverSeriesWithoutFirstData

for

CursorLegendIC.ItemsSource= this.RolloverSeriesWithoutFirstData

Or as You can see in the above answer, remove code behind and use clear mvvm