1

this is xaml part

<ItemsControl x:Name="EventsTop">
                    <ItemsControl.ItemTemplate>
                        <DataTemplate>
                            <StackPanel Margin="0,1,0,0">
                                <Button Content="{Binding Name}" Template="{DynamicResource ButtonFirst}" Height="50" Margin="15,0,0,0" Padding="10,0,15,0" FontSize="19" FontFamily="/Resources/Fonts/Font Awesome/#FontAwesome" BorderThickness="5,0,0,0" BorderBrush="#8CC152" Background="#2980B9" HorizontalContentAlignment="Left" Foreground="Black" Click="TabOpen" Tag="{Binding Id}"></Button>
                                <StackPanel Background="#2980B9" Margin="15,0,0,5" Visibility="Collapsed" AllowDrop="True" Tag="{Binding Id}" Drop="RowDrop">
                                    <Border BorderThickness="5,0,0,0" BorderBrush="#8CC152">
                                        <StackPanel>
                                            <DockPanel LastChildFill="False">
                                                <Label DockPanel.Dock="Left" Width="140" Content="Date" FontSize="19" BorderThickness="0,0,0,1"   FontFamily="/Resources/Fonts/Open Sans/#Open Sans" BorderBrush="Black" HorizontalContentAlignment="Center"></Label>
                                                <Label DockPanel.Dock="Left" Width="190" Content="Event"  FontSize="19" BorderThickness="0,0,0,1" FontFamily="/Resources/Fonts/Open Sans/#Open Sans" BorderBrush="Black" HorizontalContentAlignment="Center"></Label>
                                                <Label DockPanel.Dock="Left" Width="100" Content="Select" FontSize="19" BorderThickness="0,0,0,1" FontFamily="/Resources/Fonts/Open Sans/#Open Sans" BorderBrush="Black" HorizontalContentAlignment="Center"></Label>
                                            </DockPanel>
                                            <ScrollViewer VerticalScrollBarVisibility="Auto" MaxHeight="150">
                                                <ItemsControl ItemsSource="{Binding Details}">
                                                    <ItemsControl.ItemTemplate>
                                                        <DataTemplate>
                                                            <DockPanel LastChildFill="False">
                                                                <Label Content="{Binding Date}" DockPanel.Dock="Left" Width="140" FontSize="19" BorderThickness="0" FontFamily="/Resources/Fonts/Open Sans/#Open Sans" BorderBrush="Black" HorizontalContentAlignment="Center"></Label>
                                                                <Label Content="{Binding EventName}" DockPanel.Dock="Left" Width="165" FontSize="19" BorderThickness="0" FontFamily="/Resources/Fonts/Open Sans/#Open Sans" BorderBrush="Black" HorizontalContentAlignment="Center"></Label>
                                                                <Border Width="97">
                                                                    <CheckBox VerticalAlignment="Center" HorizontalAlignment="Center" IsChecked="{Binding Checked}"></CheckBox>
                                                                </Border>
                                                                <Button Width="25" DockPanel.Dock="Left" Content="&#xf08d;" BorderThickness="0" Background="Transparent"  FontFamily="/Resources/Fonts/Font Awesome/#FontAwesome"></Button>
                                                            </DockPanel>
                                                        </DataTemplate>
                                                    </ItemsControl.ItemTemplate>
                                                </ItemsControl>
                                            </ScrollViewer>
                                        </StackPanel>
                                    </Border>
                                </StackPanel>
                            </StackPanel>
                        </DataTemplate>
                    </ItemsControl.ItemTemplate>
                </ItemsControl>

this is xaml.cs

 private void WindowLoaded(object sender, RoutedEventArgs e)
    {
        EventHelper eventHelper = new EventHelper();

        TopEvents = eventHelper.GetSports(EventHelper.EventGroup.Top);
        foreach (Sport item in TopEvents)
        {
            item.Name = "\uf196 " + item.Name;
        }
        EventsTop.ItemsSource = TopEvents;

        AllEvents = eventHelper.GetSports(EventHelper.EventGroup.All);
        foreach (Sport item in AllEvents)
        {
            item.Name = "\uf196 " + item.Name;
        }
        EventsAll.ItemsSource = AllEvents;

        Sport.ItemsSource = eventHelper.GetSports(EventHelper.EventGroup.All);
    }

    private void RowMouseDown(object sender, MouseButtonEventArgs e)
    {
        DockPanel currentRow = (DockPanel) sender;
        int rowOffset = Convert.ToInt32(currentRow.Tag);
        DragDrop.DoDragDrop(currentRow,rowOffset,DragDropEffects.Copy);
    }

    private void RowDrop(object sender, DragEventArgs e)
    {
        int rowOffset = (int) e.Data.GetData(typeof (int));
        AllEvents[0].Name = "1";
    }

Also my model in collection

class Sport : INotifyPropertyChanged
{
    private int _id;
    private string _name = string.Empty;
    private ObservableCollection<Details> _details = new ObservableCollection<Details>();

    public int Id
    {
        get { return _id; }
        set { _id = value; }
    }

    public string Name
    {
        get { return _name; }
        set
        {
            _name = value;
            NotifyPropertyChanged("Content");
        }
    }

    public ObservableCollection<Details> Details
    {
        get { return _details; }
        set { _details = value; }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    private void NotifyPropertyChanged(string info)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(info));
            MessageBox.Show(info);
        }
    }
}

So when I am changing property its throwing MessageBox but not updating GUI.

I xaml.cs I am calling methods GetEvents thats return ObservableCollection

I want to change Name in Sport which is in ObservableCollaction<Sport> AllEvents

You can see it in RowDrop method in xaml.cs In debugging I notice that AllEvents[0].Name was changed but view was not updating

UPDATE

Part of ObservabelCollection declaration

public MainPage()
    {
        InitializeComponent();
        AllEvents = new ObservableCollection<Sport>();
        TopEvents = new ObservableCollection<Sport>();
        EventsTop.ItemsSource = TopEvents;
        EventsAll.ItemsSource = AllEvents;
    }

    private ObservableCollection<Sport> AllEvents;
    private ObservableCollection<Sport> TopEvents;

UPDATE SECOND I caught that when I am using window activated event it is working

Aren Hovsepyan
  • 1,947
  • 2
  • 17
  • 45

4 Answers4

4

I found solution.

So, ObservableCollection is working very well but,It needs to be refreshed for appearing in view and for it we need to use

CollectionViewSource.GetDefaultView(ObservableCollection).Refresh() method for it

I think it will help someone

Aren Hovsepyan
  • 1,947
  • 2
  • 17
  • 45
  • This did it for me. Thank you very much for sharing! I have been spending the last two days trying to figure out why my view doesn't update – martin36 Sep 08 '20 at 13:46
2

The problem with property named passed to NotifyPropertyChanged method. The name of parameter should be property name. Please change the Name property as

public string Name
    {
        get { return _name; }
        set
        {
            _name = value;
            NotifyPropertyChanged("Name");
        }
    }
user1672994
  • 10,509
  • 1
  • 19
  • 32
1

Use CallerMemberNameAttribute to avoid having to get the name correct and allowing refactoring:

private void NotifyPropertyChanged([CallerMemberName] string info = null)
{
    if (PropertyChanged != null)
    {
        PropertyChanged(this, new PropertyChangedEventArgs(info));
        MessageBox.Show(info);
    }
}

public string Name
{
    get { return _name; }
    set
    {
        _name = value;
        NotifyPropertyChanged(); //now no need to specify
    }
}

Every property setter should notify property change, so:

public IEnumerable<Details> Details //note IEnumerable, no calling code needs to know its concrete type
{
    get { return _details; }
    set
    {
        _details = value;
        NotifyPropertyChanged();
    }
}

And with an observable range collection you could do this:

private readonly ObservableRangeCollection<Details> _details = new ObservableRangeCollection<Details>();

public IEnumerable<Details> Details
{
    get { return _details; }
    set { _details.Replace(value); }
}
Community
  • 1
  • 1
weston
  • 54,145
  • 21
  • 145
  • 203
  • Good points on the way to implement INotifyPropertyChanged and they should be helpful for OP, but the collection that requires refresh in this case is AllEvents which seems to be a part of the actual view instead a viewmodel. And the collection is never "re-set" in this case. – Janne Matikainen Nov 22 '15 at 20:04
0

From MSDN.

Occurs when an item is added, removed, changed, moved, or the entire list is refreshed.

The changed does not mean when child properties are changed, but when you change the item at any index.

So when you modify a collection item you will need to notify the binding that the property was changed. From your window's viewmodel after you have modified the item in the collection, you would notify that the collection was changed.

NotifyPropertyChanged("AllEvents"); 
Janne Matikainen
  • 5,061
  • 15
  • 21