2014-11-17 3 views
0

У меня есть ItemControl, который имеет Canvas как ItemPanelTemplate и эллипс как ItemTemplate. То, что я хочу сделать, это когда я перетаскиваю существующий Ellipse, я хочу, чтобы он был удален из моей наблюдаемой коллекции объектов EllipseXY, то есть он также будет удален из моего Canvas. Событие перетаскивания проходит по объекту EllipseXY, который затем можно сравнить в событии Drop. Однако, когда я удаляю объект EllipseXY в моей коллекции, он остается на моем холсте, несмотря на то, что Remove был запущен. Каковы могут быть возможные причины?Проблема удаления объектов из наблюдаемой коллекции

Модель:

public class EllipseXY 
{ 
    public double X { get; set; } 
    public double Y { get; set; } 
    public Ellipse EllipseObject { get; set; } 
} 

ViewModel:

private ObservableCollection<EllipseXY> ellipses; 
    public ObservableCollection<EllipseXY> Ellipses 
    { 
     get { return ellipses; } 
     set 
     { 
      if (ellipses == null) 
      { 
       ellipses = new ObservableCollection<EllipseXY>(); 
       ellipses = value; 
      } 
      else 
      { 
       ellipses = value; 

      } 
RaisePropertyChanged("Ellipses"); 
     } 
    } 

#region EllipseXY 
    public EllipseXY EllipseXY 
    { 
     get { return ellipsexy; } 
     set 
     { 
      ellipsexy = value; 
      RaisePropertyChanged("EllipseXY"); 
     } 
    } 

    public Ellipse EllipseObject 
    { 
     get { return ellipsexy.EllipseObject; } 
     set 
     { 
      ellipsexy.EllipseObject = value; 
      RaisePropertyChanged("EllipseObject"); 
     } 
    } 

    public double X 
    { 
     get { return ellipsexy.X; } 
     set 
     { 
      ellipsexy.X = value; 
      RaisePropertyChanged("X"); 
     } 
    } 

    public double Y 
    { 
     get { return ellipsexy.Y; } 
     set 
     { 
      ellipsexy.Y = value; 
      RaisePropertyChanged("Y"); 
     } 
    } 
    #endregion 

Drag:

DataObject dragObject= new DataObject("dragObject", elliXY); 
DragDrop.DoDragDrop(dragEllipse, dragObject, DragDropEffects.Move); 

падения (не весь код, но только отношение один к этому вопросу):

Model.EllipseXY ellipseXY = (Model.EllipseXY)e.Data.GetData("dragObject"); 
Ellipses.Remove(ellipseXY); 

Я также попытался с помощью LINQ:

 EllipseXY test = (EllipseXY)Ellipses.Where(ellipse => ellipse.EllipseObject.Fill == dropEllipse.Fill); 
     Ellipses.Remove(test); 

Но без успеха: P

Edit XAML:

<ItemsControl ItemsSource="{Binding Ellipses}" DockPanel.Dock="Top"> 
      <ItemsControl.ItemsPanel> 
       <ItemsPanelTemplate> 
        <Canvas Name="CanvasDrop" Margin="10,0,10,0" Width="500" Height="400" 
          ClipToBounds="True" Background="{Binding Image}" AllowDrop="True" IsItemsHost="True"> 
         <i:Interaction.Triggers> 
          <i:EventTrigger EventName="MouseMove"> 
           <gala:EventToCommand Command="{Binding DragCommand}" PassEventArgsToCommand="True" /> 
          </i:EventTrigger> 
          <i:EventTrigger EventName="Drop"> 
           <gala:EventToCommand Command="{Binding DropCommand}" PassEventArgsToCommand="True" /> 
          </i:EventTrigger> 
         </i:Interaction.Triggers> 
        </Canvas> 
       </ItemsPanelTemplate> 
      </ItemsControl.ItemsPanel> 
      <ItemsControl.ItemContainerStyle> 
       <Style TargetType="ContentPresenter"> 
        <Setter Property="Canvas.Left" Value="{Binding Path=X}"/> 
        <Setter Property="Canvas.Top" Value="{Binding Path=Y}"/> 
       </Style> 
      </ItemsControl.ItemContainerStyle> 
      <ItemsControl.ItemTemplate> 
       <DataTemplate DataType="Ellipse"> 
        <Ellipse Fill="{Binding EllipseObject.Fill}" Style="{StaticResource ellipseStyle}" /> 
       </DataTemplate> 
      </ItemsControl.ItemTemplate> 
     </ItemsControl> 
+0

Можете ли вы показать, как ваш 'ItemsControl' связывается с списком« Ellipses »? –

+0

Попробуйте открытый класс EllipseXY: INotifyPropertyChanged – Vishal

+1

@Farzi: Как это должно помочь? Вопрос заключается не в изменении каких-либо атрибутов экземпляра «EllipseXY», а в изменении списка. –

ответ

2

Элемент, который вы передаете до Remove должен быть таким же экземпляром, а не только объектом, который имеет те же значения.

Я подозреваю, что в настоящее время не так, так как ваш фильтр на основе свойств элементов сделал трюк, как описан в вашем комментарии:

EllipseXY test = (EllipseXY)Ellipses.First(ellipse => ellipse.EllipseObject.Fill == dropEllipse.Fill); 
Ellipses.Remove(test); 

Как это, test ссылки на текущем экземпляре, который находится в списке , который соответствует выражению фильтра.

Вы можете еще больше сузить свой выбор, либо путем создания более сложного логическое выражение ((ellipse.EllipseObject.Fill == dropEllipse.Fill) && (ellipse ...), или вставив несколько вызовов Where перед вызовом First, по одному для каждого критерия.

1

Это просто странно,
Если эллипсы равно нулю значение игнорируется и не вызывайте RaisePropertyChanged.

public ObservableCollection<EllipseXY> Ellipses 
{ 
    get { return ellipses; } 
    set 
    { 
     if (ellipses == null) ellipses = new ObservableCollection<EllipseXY>(); 
     else 
     { 
      ellipses = value; 
      RaisePropertyChanged("Ellipses"); 
     } 
    } 
} 

Здесь у вас есть другая Уведомлять от собственности

public EllipseXY EllipseXY 
{ 
    get { return ellipsexy; } 
    set 
    { 
     ellipsexy = value; 
     RaisePropertyChanged("Ellipse"); 
    } 
} 

Что такое llipses?

Ваш код не становится лучше

private ObservableCollection<EllipseXY> ellipses; 
public ObservableCollection<EllipseXY> Ellipses 
{ 
    get { return ellipses; } 
    set 
    { 
     if (ellipses == null) 
     { 
      ellipses = new ObservableCollection<EllipseXY>(); 
      ellipses = value; 
     } 
     else 
     { 
      ellipses = value; 
      RaisePropertyChanged("Ellipses"); 
     } 
    } 
} 

почему бы вы установили эллипсы = новый ObservableCollection(); затем сразу же установите значение ellipses = value;
Почему RaisePropertyChanged («Эллипсы»); в другом?

Попробуйте

private ObservableCollection<EllipseXY> ellipses = new ObservableCollection<EllipseXY>(); 
public ObservableCollection<EllipseXY> Ellipses 
{ 
    get { return ellipses; } 
    set 
    { 
     if (ellipses == value) return; 
     ellipses = value; 
     RaisePropertyChanged("Ellipses"); 
    } 
} 

Чтобы добавить ответ от Mapper
Это линия, которая, вероятно, разбивая его

DataObject dragObject= new DataObject("dragObject", elliXY); 

Вы создаете новый объект
Другим решением является переопределить GetHashCode и Equals в EllipseXY

+0

Хотя это абсолютно правильно во всех аспектах, это не отвечает на вопрос; Я думаю, что это больше подходит для комментариев. –

+0

Он не копировал вставить все, что должен сказать, эллипсы :). Спасибо, что указали на игнорирование значения, а также опечатку raisepropertychanged. – Citroenfris

+0

@NielsW Затем исправьте вопрос. – Paparazzi