我在同一个窗口中有2个listviews 第一个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
}
First 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 :(得分:1)
属性ImageFileName
应该对属性内容的任何更改提出PropertyChange event
,以便UI可以相应地进行刷新。
宣言应该是这样的:
private ImageFileViewModel imageFileName;
public ImageFileViewModel ImageFileName
{
get
{
return imageFileName;
}
set
{
if(imageFileName != value)
{
imageFileName = value;
OnPropertyChanged("ImageFileName");
}
}
}
如果您希望两个ListBox同步:
First ListBox:
<ListBox Name="ListViewImage"
SelectedItem="{Binding ImageFileName}"/>
第二个ListBox:
<ListBox Name="ImageNameListBox"
SelectedItem="{Binding SelectedItem, ElementName=ListViewImage}"/>
答案 1 :(得分:1)
除了Rohits的回答,如果 ImageViewModel.ImageFileName 应该包含ListView中的所选项,那么您还需要将 ListView.SelectedItem 绑定到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 。
请注意,列表框包含 ImageViewModel 类型的项目,因为:
<ListBox
ItemsSource="{Binding AllImages}"
...
/>
现在,任何可能的选定项目也将是 ImageViewModel ,而不是 ImageViewModel.FileName 。因此,您的ListBox应该设置为类似于:
<ListBox Height="65"
ItemsSource="{Binding AllImages}"
SelectedItem="{Binding ImageFileName}"
DisplayMemberPath="FileName.LastName"
...
/>
的更新强>:
非常努力地眯起眼睛,在代码中发现了另一个可能的问题。
ImageFileCollectionViewModel 应该作为ListView 和 ListBox的DataContext,仅分配给 ListView.DataContext
要将 ImageFileCollectionViewModel 也作为 ListBox 的DataContext应用,请明确指定:
ImageFileCollectionViewModel ImagesViewModel = new ImageFileCollectionViewModel();
ImageFileControler.CompleteViewList(ImagesViewModel, destination_dir);
ListViewImage.DataContext = ImagesViewModel;
ImageNameListBox.DataContext = ImagesViewModel;
或者只是将DataContext设置在父/祖先容器UIElement上,如果ListView和ListBox碰巧共享同一个父/祖先。