WPF: ListView & Bearbeiten ListViewItem
Ich möchte in der Lage sein, um wählen Sie ein Element aus, und Bearbeiten Sie dann Ihre label:
- Wählen Sie ein Element
- Element markiert ist
- Klicken Sie auf label
- Label TextBlock ersetzt wird, mit Textfeld
- Ändern Sie die Beschriftung
- Nur ein Element bearbeitet werden kann in einer Zeit,
Ende der Bearbeitung:
- Klicken Sie auf Element Symbol:
- TextBox ersetzt, wieder mit TextBlock
- Element bleibt markiert
- Ein anderes Element geklickt wird:
- TextBox ersetzt, wieder mit TextBlock
- Bearbeitete Element deaktiviert ist
- Angeklickte Element ausgewählt und markiert
- Jedem anderen Bereich des Fensters geklickt wird:
- TextBox ersetzt, wieder mit TextBlock
- Bearbeitete Element bleibt markiert
Verhalten sollte ziemlich genau so, wie im Windows Explorer.
Habe ich es geschafft, zu erreichen, die meisten der Anforderungen. Trotzdem bekomme ich zufällige Ergebnisse. Zum Beispiel beim ersten Start konnte ich auf der gerade auf label, um es zu Bearbeiten. Das Element selbst bleibt nicht hervorgehoben. Dies tritt nur beim start.
Auch mit der scroll-Leiste nicht den Fokus aus der Liste Element. Dies ermöglicht das Bearbeiten mehrerer Elemente auf der gleichen Zeit.
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>
Code
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; }
}
}
Dank für das Lesen des langen post.
Ich habe gesucht und gelesen, dass viele Antworten hier bei StackOverflow, aber keiner von Ihnen waren großartig für mich.
Beispiel:
- Wie kann ein Griff mit einem Mausklick außerhalb der Kontrolle?
- Wie behandeln Sie das Ereignis beim klicken auf den leeren Raum?
- Wie zu erfassen, ein Mausklick auf einen Eintrag in einer ListBox in WPF?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Können Sie erfassen möchten das scrollevent für das listview und explizit entfernen Sie den Fokus auf das element.
ist und in der Prozedur entfernen zu konzentrieren.
Blick auf diesen stackoverflow-Seite für verschieben den Fokus Weg von den Elementen
WPF: Wie Sie programmgesteuert entfernen der Fokus von einem Textfeld
Vielleicht ist es besser zu wechseln IsReadonly-Eigenschaft in verschiedenen Staaten? Dann werden Sie nicht mehr wechseln müssen Sichtbarkeit. Auch, es ist besser, zu ersetzen, die Vorlagen in diesem Fall.