2014-01-19 4 views
0

У меня есть 2 просмотра в одном окне Первый списокView, который загружает изображение с изображением & Название изображения. Во втором списке-списке я хочу обновить выбранное имя/имя изображения &, предлагая пользователю удалить или просмотреть выбранные изображения нажатием кнопки.WPF: Получить выбранные значения Переплет ListView

Я следил за этой статьей (http://www.clear-lines.com/blog/post/Selecting-an-item-in-a-list-with-WPF-and-M-V-VM.aspx), но мне не удалось получить выбранные элементы путем привязки. Как я могу получить выбранное имя/имя изображения из модели.

Код:

//ImageFile Collection Model 
public class ImageFileCollectionViewModel: INotifyPropertyChanged 
    { 
     private ObservableCollection<ImageFileViewModel> _allImages; 
     private int dataItemsCount; 

     public ObservableCollection<ImageFileViewModel> AllImages 
     { 
      get { return _allImages; } 
     } 

     public int DataItemsCount 
     { 
      get 
      { 
       return dataItemsCount; 
      } 
      private set 
      { 
       dataItemsCount = value; 
       OnPropertyChanged("DataItemsCount"); 
      } 
     } 

     public ImageFileCollectionViewModel() 
     { 
      this._allImages = new ObservableCollection<ImageFileViewModel>(); 
      this.DataItemsCount = 0; 
     } 

     public void AddNewPhotoItem(IImageFile imageFile) 
     { 
      ImageFileViewModel newImageFileViewModel = new ImageFileViewModel(imageFile); 
      this._allImages.Add(newImageFileViewModel); 
      this.DataItemsCount++; 
     } 

     public event PropertyChangedEventHandler PropertyChanged; 

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

     public ImageFileViewModel ImageFileName { get; set; }// To get the selected Image name 
    } 

Первый ListView:

string destination_dir = System.IO.Directory.GetCurrentDirectory() + @"./4x6"; 
ImageFileCollectionViewModel ImagesViewModel = new ImageFileCollectionViewModel(); 
ImageFileControler.CompleteViewList(ImagesViewModel, destination_dir); 
ListViewImage.DataContext = ImagesViewModel; 

Xaml:

<ListView SelectionMode="Multiple" x:Name="ListViewImage" Width="Auto" 
       ItemsSource="{Binding Path=AllImages}" Margin="0,20,0,0" 
       VirtualizingStackPanel.IsVirtualizing="True" 
       VirtualizingStackPanel.VirtualizationMode= "Recycling" Height="333" VerticalAlignment="Top"> 
      <ListView.ItemTemplate> 
       <DataTemplate> 
        <DataTemplate.Resources> 
         <Storyboard x:Key="WaitingTimeline" Timeline.DesiredFrameRate="10"> 
          <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" RepeatBehavior="Forever" 
          Storyboard.TargetName="WaitingImage" 
          Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0] 
                 .(RotateTransform.Angle)"> 
           <SplineDoubleKeyFrame KeyTime="00:00:00" Value="-15"/> 
           <SplineDoubleKeyFrame KeyTime="00:00:03" Value="15"/> 
          </DoubleAnimationUsingKeyFrames> 
         </Storyboard> 
        </DataTemplate.Resources> 

        <StackPanel Orientation="Horizontal" Height="100"> 

         <Image x:Name="ThumbnailImage" Margin="2" Visibility="Collapsed" Height="120" Width="180" Source="{Binding Path=Thumbnail}" > 
          <Image.BitmapEffect> 
           <DropShadowBitmapEffect ShadowDepth="5" /> 
          </Image.BitmapEffect> 

         </Image> 
         <Image x:Name="WaitingImage" Visibility="Visible" Height="20" Width="20" Source="./Hourglass.png"> 
          <Image.RenderTransform> 
           <TransformGroup> 
            <RotateTransform Angle="0" CenterX="10" CenterY="10"/> 
           </TransformGroup> 
          </Image.RenderTransform> 

         </Image> 

         <TextBlock Margin="10,40,0,0" Text="{Binding Path=ShortName}" /> 
        </StackPanel> 

        <DataTemplate.Triggers> 
         <DataTrigger Binding="{Binding Path=IsLoaded}" Value="True"> 
          <Setter Property="Visibility" TargetName="ThumbnailImage" Value="Visible"/> 
          <Setter Property="Visibility" TargetName="WaitingImage" Value="Collapsed"/> 
         </DataTrigger> 

         <DataTrigger Binding="{Binding Path=IsLoaded}" Value="False"> 
          <Setter Property="Visibility" TargetName="WaitingImage" Value="Visible"/> 
          <Setter Property="Visibility" TargetName="ThumbnailImage" Value="Collapsed"/> 
          <DataTrigger.EnterActions> 
           <BeginStoryboard x:Name="WaitingTimeline_BeginStoryboard" Storyboard="{StaticResource WaitingTimeline}"/> 
          </DataTrigger.EnterActions> 
          <DataTrigger.ExitActions> 
           <StopStoryboard BeginStoryboardName="WaitingTimeline_BeginStoryboard"/> 
          </DataTrigger.ExitActions> 
         </DataTrigger> 
        </DataTemplate.Triggers> 
       </DataTemplate> 
      </ListView.ItemTemplate> 

     </ListView> 

Второй ListView, чтобы получить выбранное изображение Имя/имена:

<StackPanel Name="secondLBox" Margin="53,369,10,31" Orientation="Vertical" > 
      <ListBox Height="65" 
       Name="ImageNameListBox" 
       ItemsSource="{Binding AllImages}" 
       DisplayMemberPath="LastName" 
       SelectedItem="{Binding Path=ImageFileName}"/> 
      <Label Content="Selected Image"/> 
      <Label Content="{Binding ImageFileName.FileName}" Visibility="Visible" Height="39"/> 

     </StackPanel> 
+0

Кроме ответа Rohits, если ImageViewModel.ImageFileName должен содержать элемент, выбранный в ListView, тогда я считаю, что вы также должны привязать ListView.SelectedItem к ImageViewModel.ImageFileName. (ListView.SelectedItem использует двустороннюю привязку по умолчанию) – elgonzo

ответ

1

Дополнительно к Rohits ответ, если ImageViewModel.ImageFileName должен содержать выбранный элемент из ListView, то вы также должны bind ListView.SelectedItem to ImageViewModel.ImageFileName. (ListView.SelectedItem использует двухсторонние связывания по умолчанию)

<ListView 
    SelectedItem="{Binding Path=ImageFileName}" 
    ... all your other stuff from the XAML 
/> 

ListView.SelectedItem связывает двухстороннее по умолчанию, так что если вы измените ImageViewModel.ImageFileName через код-сзади или через другое закрепление, выбор в ListView будет соответствующим образом изменяться (предполагая, что вы также следовали совету Rohit).


У вас также есть ошибка в ListBox предотвращения увидеть ImageViewModel.ImageFileName.

Обратите внимание, что ListBox содержит элементы типа ImageViewModel, из-за:

<ListBox 
    ItemsSource="{Binding AllImages}" 
    ... 
/> 

Теперь, любой возможный выбранный элемент будет также быть ImageViewModel, не ImageViewModel.FileName. Таким образом, ваш ListBox должен быть настроен примерно так:

<ListBox Height="65" 
    ItemsSource="{Binding AllImages}" 
    SelectedItem="{Binding ImageFileName}" 
    DisplayMemberPath="FileName.LastName" 
    ... 
/> 


UPDATE:

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

ImageFileCollectionViewModel якобы служит DataContext для ListView и в ListBox является только назначен ListView.DataContext.

Чтобы иметь ImageFileCollectionViewModel также применяется в качестве DataContext из ListBox, либо назначить его explicetly:

ImageFileCollectionViewModel ImagesViewModel = new ImageFileCollectionViewModel(); 
ImageFileControler.CompleteViewList(ImagesViewModel, destination_dir); 
ListViewImage.DataContext = ImagesViewModel; 
ImageNameListBox.DataContext = ImagesViewModel; 

или просто установить DataContext на родителя/предка контейнера UIElement, если оба ListView и у ListBox есть один и тот же родитель/предок.

+0

Я следил точно за твоими и Рохитами, но я не вижу никакого значения. – linguini

+0

Я обновил свой ответ. Ваш список был настроен некорректно ... – elgonzo

+0

Возможно, вам понадобится 'DisplayMemberPath =" (FileName.LastName) "(отметим скобки) из-за точки. Но я не совсем уверен, нужно ли вам это делать, поскольку у меня нет способа проверить это. – elgonzo

1

Недвижимость ImageFileName должно поднять PropertyChange event при любом изменении содержимого контента, чтобы пользовательский интерфейс мог соответственно обновиться.

Декларация должна быть такой:

private ImageFileViewModel imageFileName; 
public ImageFileViewModel ImageFileName 
{ 
    get 
    { 
     return imageFileName; 
    } 
    set 
    { 
     if(imageFileName != value) 
     { 
     imageFileName = value; 
     OnPropertyChanged("ImageFileName"); 
     } 
    } 
} 

Если вы хотите как ListBox быть синхронизированы:

  1. Bind SelectedItem для первого ListBox с ImageFileName.
  2. Bind SelectedItem для второго ListBox с SelectedItem первого ListBox.

Первый ListBox:

<ListBox Name="ListViewImage" 
     SelectedItem="{Binding ImageFileName}"/> 

Второй ListBox:

<ListBox Name="ImageNameListBox" 
     SelectedItem="{Binding SelectedItem, ElementName=ListViewImage}"/> 
+0

Да, я забыл спасибо. Тем не менее, я не вижу никакого значения во втором списке, когда я нажимаю в первом LV. – linguini

+0

@linguini, см. Мой комментарий ниже вашего вопроса (я поставил его как комментарий, так как я сначала не был уверен в том, что именно вы пытались достичь) – elgonzo

+0

@ linguini- См. Обновление в ответ. Надеюсь, я правильно понял вашу проблему. –

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