2015-11-22 3 views
0

это XAML частьWPF ObservableCollection не обновляя вид

<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> 

это 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"; 
    } 

Кроме моей модели в коллекции

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); 
     } 
    } 
} 

Так что, когда я меняю свойство ИТС бросая MessageBox, но не обновляя GUI.

Я xaml.cs Я зову Методы GetEvents Thats возвращения ObservableCollection

Я хочу изменить Name в Sport, который находится в ObservableCollaction<Sport> AllEvents

Вы можете увидеть его в RowDrop методе в xaml.cs при отладке Я заметил, что AllEvents[0].Name был изменен, но просмотр не обновлялся.

ОБНОВЛЕНИЕ

Часть ObservabelCollection декларации

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 ВТОРОГО Я поймал, что, когда я использую окно активировано событие это работает

+1

Заменить 'NotifyPropertyChanged (« Content »);' by 'NotifyPropertyChanged (« Name »);'. – Clemens

+0

Привет, я изменил его, но он еще не работает –

+0

Показывает код, в котором вы меняете значение. Это строка: 'AllEvents [0] .Name =" 1 ";'? – weston

ответ

2

Проблемы с свойством с именем передается NotifyPropertyChanged методы. Имя параметра должно быть именем свойства. Пожалуйста, измените свойство Имя в

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

Привет, я изменил его, но он еще не работает –

+0

Что делает 'Template =" {DynamicResource ButtonFirst} "' он переопределяет содержание dp кнопки? – user1672994

+0

Его просто шаблон для кнопки –

0

Использование CallerMemberNameAttribute, чтобы избежать того, чтобы получить имя правильно и позволяет рефакторинга:

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 
    } 
} 

Каждое свойство сеттер должен уведомить об изменении свойств, так:

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

И с observable range collection вы можете это сделать:

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

public IEnumerable<Details> Details 
{ 
    get { return _details; } 
    set { _details.Replace(value); } 
} 
+0

Хорошие точки на пути реализации INotifyPropertyChanged, и они должны быть полезны для OP, но коллекция, требующая обновления в этом случае, - это AllEvents, которая, кажется, является частью фактического представления, а не viewmodel. И в этом случае коллекция никогда не будет «повторно установлена». –

0

От MSDN.

Происходит, когда предмет будет добавлен, удален, изменен, перемещен или обновлен весь список .

Измененное не означает, когда свойства дочернего объекта изменены, но при изменении элемента по любому индексу.

Поэтому, когда вы изменяете элемент коллекции, вам необходимо уведомить об обязательном изменении свойства. Из модели просмотра вашего окна после того, как вы изменили элемент в коллекции, вы должны уведомить об изменении коллекции.

NotifyPropertyChanged("AllEvents"); 
0

Я нашел решение.

Так, ObservableCollection работает очень хорошо, но это нужно обновить для появления в поле зрения и для этого нам нужно использовать

CollectionViewSource.GetDefaultView(ObservableCollection).Refresh() метод для него

Я думаю, что это поможет кому-то

Смежные вопросы