我希望能够选择一个项目,然后编辑其标签:
结束编辑:
行为应该与Windows资源管理器中的行为非常相似。
我设法完成了大部分要求。我仍然得到随机结果。例如,在第一次启动时,我可以直接点击标签进行编辑。项目本身不会突出显示。这只在开始时发生。
同样使用滚动条不会将焦点从列表项中移开。这允许同时编辑多个项目。
XAML
<Window x:Class="WPFComponents.DailyImages"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:Model="clr-namespace:WPFComponents.Model"
Title="Media Items" Height="300" Width="300">
<ListView x:Name="_mediaItemList" ItemsSource="{Binding MediaItems}" ScrollViewer.HorizontalScrollBarVisibility="Disabled" SelectionMode="Multiple"
MouseLeftButtonDown="OnClickMediaList" IsSynchronizedWithCurrentItem="True">
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="IsSelected" Value="{Binding IsSelected}" />
</Style>
</ListView.ItemContainerStyle>
<ListView.ItemTemplate>
<DataTemplate DataType="Model:MediaItem">
<Grid Width="80" Margin="4">
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<Image HorizontalAlignment="Center" Stretch="Uniform" Source="{Binding Path=IconPath}" Width="70" />
<StackPanel Grid.Row="2">
<TextBlock Text="{Binding Path=Date}" TextWrapping="Wrap" />
<TextBlock x:Name="_labelTextBlock" Text="{Binding Path=Label}" TextWrapping="Wrap"
PreviewMouseLeftButtonDown="OnClickLabelBlock">
<TextBlock.Style>
<Style TargetType="TextBlock">
<Setter Property="Visibility" Value="Visible" />
</Style>
</TextBlock.Style>
</TextBlock>
<TextBox x:Name="_labelTextBox" Text="{Binding Path=Label}" Visibility="Collapsed"
TextWrapping="WrapWithOverflow" TextAlignment="Center"
LostFocus="OnTextLostFocus">
</TextBox>
</StackPanel>
</Grid>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding IsEditing}" Value="True">
<Setter TargetName="_labelTextBlock" Property="Visibility" Value="Collapsed" />
<Setter TargetName="_labelTextBox" Property="Visibility" Value="Visible" />
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</ListView.ItemTemplate>
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel IsItemsHost="True" VerticalAlignment="Top" />
</ItemsPanelTemplate>
</ListView.ItemsPanel>
</ListView>
代码
public partial class DailyImages
{
public DailyImages()
{
InitializeComponent();
ViewModel.DailyImages dailyImages = new ViewModel.DailyImages();
_mediaItemList.DataContext = dailyImages;
}
private void OnClickLabelBlock(object sender, MouseButtonEventArgs e)
{
TextBlock notes = sender as TextBlock;
if (notes == null) return;
MediaItem selectedMedia = notes.DataContext as MediaItem;
if (selectedMedia == null) return;
// Multiple items might be selected
// Clear all selected items
_mediaItemList.SelectedItems.Clear();
// Reselect
selectedMedia.IsSelected = true;
selectedMedia.IsEditing = true;
Mouse.Capture(this, CaptureMode.SubTree);
}
private void OnTextLostFocus(object sender, RoutedEventArgs e)
{
TextBox textBox = sender as TextBox;
if (textBox == null) return;
MediaItem mediaItem = textBox.DataContext as MediaItem;
if (mediaItem == null)
return;
// End the label editing
mediaItem.IsEditing = false;
ReleaseMouseCapture();
}
private void OnClickMediaList(object sender, MouseButtonEventArgs e)
{
// End the label editing
foreach (MediaItem mediaItem in _mediaItemList.Items)
mediaItem.IsEditing = false;
ReleaseMouseCapture();
}
}
MediaItem.cs
public class MediaItem : INotifyPropertyChanged
{
private bool _isEditing;
private bool _isSelected;
private string _label;
public MediaItem()
{
IsEditing = false;
_isSelected = false;
}
public bool IsEditing
{
get { return _isEditing; }
set
{
if (_isEditing == value) return;
_isEditing = value;
OnPropertyChanged("IsEditing");
}
}
public string Label
{
get { return _label; }
set
{
_label = value;
OnPropertyChanged("Label");
}
}
public DateTime Date { get; set; }
public string IconPath { get; set; }
public bool IsSelected
{
get { return _isSelected; }
set
{
_isSelected = value;
OnPropertyChanged("IsSelected");
}
}
public event PropertyChangedEventHandler PropertyChanged;
[NotifyPropertyChangedInvocator]
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}
}
DailyImages.cs
public class DailyImages
{
private ObservableCollection<MediaItem> _mediaItems;
public DailyImages()
{
_mediaItems = new ObservableCollection<MediaItem>();
_mediaItems.Add(new MediaItem {Label = "Image 1", IconPath = "Resources/Icon1.png"});
_mediaItems.Add(new MediaItem {Label = "Image 2", IconPath = "Resources/Icon2.png"});
_mediaItems.Add(new MediaItem {Label = "Image 3", IconPath = "Resources/Icon3.png"});
_mediaItems.Add(new MediaItem {Label = "Image 4", IconPath = "Resources/Icon4.png"});
_mediaItems.Add(new MediaItem {Label = "Image 5", IconPath = "Resources/Icon5.jpg"});
_mediaItems.Add(new MediaItem {Label = "Image 6", IconPath = "Resources/Icon6.png"});
_mediaItems.Add(new MediaItem {Label = "Image 7", IconPath = "Resources/Icon7.png"});
_mediaItems.Add(new MediaItem {Label = "Image 8", IconPath = "Resources/Icon8.png"});
_mediaItems.Add(new MediaItem {Label = "Image 9", IconPath = "Resources/Icon9.png"});
}
public ObservableCollection<MediaItem> MediaItems
{
get { return _mediaItems; }
set { _mediaItems = value; }
}
}
感谢阅读长篇文章。
我在StackOverflow中搜索并阅读了很多答案,但这些答案对我来说都不是很好。
例如:
答案 0 :(得分:0)
您可能希望捕获listview上的scrollevent并显式删除对元素的焦点。
ScrollViewer scrollViewer = GetVisualChild<ScrollViewer>(mTreeView);
scrollViewer.ScrollChanged += new ScrollChangedEventHandler(scrollViewer.....
并在处理程序中删除焦点。
查看此stackoverflow页面,将焦点从元素移开 WPF: How to programmatically remove focus from a TextBox
答案 1 :(得分:0)
也许最好在不同状态下切换IsReadonly属性?然后,您将不再需要切换可见性。此外,在这种情况下更换模板更好。