![](/img/trans.png)
[英]ListView that have its .itemssource set to a list but doesn't update when I add item to the list
[英]Getting 'IsMouseOver' to work on a ListView when ItemsSource is set to a list
我有一個WPF項目,我在其中創建了一個UserControl,目的是制作一個自定義ListViewItem,其中包括一個關閉按鈕。 這是該代碼:
<ListViewItem x:Name="lviTab" Height="36" Background="#232323"
MouseUp="LviTab_MouseUp" MouseEnter="LviTab_MouseEnter">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding TabText}" FontSize="15" />
<ListViewItem x:Name="lviTabClose" Margin="5, 0, 0, 0"
Padding="0, 0, 0, 0" MouseUp="LviTabClose_MouseUp">
<materialDesign:PackIcon Kind="Close" Foreground="White"
VerticalAlignment="Center"
HorizontalAlignment="Center" Width="20" Height="20" />
</ListViewItem>
</StackPanel>
</ListViewItem>
我通過將UserControl內的TextBlock的文本綁定到另一個類TabData.cs來調整每個項目內的文本
public class TabData : UIElement
{
public TabData() : base()
{
}
public string TabText { get; set; }
}
在我的ListView中,我已將DataTemplate設置為UserControl。 我已經將ListView ItemSource設置為TabData對象的列表。
tabs = new List<TabData>()
{
new TabData{TabText = "Tab 1"},
new TabData{TabText = "Tab 2"},
new TabData{TabText = "Tab 3"},
new TabData{TabText = "Tab 4"},
new TabData{TabText = "Tab 5"}
};
lvTabs.ItemsSource = tabs;
將鼠標移到ListViewItem上時,我需要IsMouseOver為true。 我嘗試將UIElement繼承到TabData,但沒有成功。 我對WPF還是很陌生,希望在使用UserControl並將ItemSource設置為沒有ListViewItems的項目時如何保留IsMouseOver屬性提供幫助。
這是要做您想做的最簡單的方法。 當用集合中的項目填充ListView時,它會創建自己的ListViewItems。 您無需在每個ListViewItems內創建另一個ListViewItem,而不必在您自己的列表內創建第三個ListViewItem。
我將省去UserControl並將該XAML直接放在模板中。 這樣做的原因是我們希望單擊處理程序位於MainWindow.xaml.cs中,並可以在其中與主視圖模型進行交互。 我們可以通過兩種不同的方式很容易地使它與UserControl一起使用,但我會盡量簡化這一過程。 理想情況下,您應該使用Command
,但這是一種特殊情況,其中MVVM中的少量雜質不會破壞您。 對於項UI像一個文本塊和一個按鈕一樣簡單的情況,UserControl超出了您的需要。
首先,MainWindow.xaml
<Window.Resources>
<DataTemplate x:Key="TabListViewItemTemplate">
<DockPanel LastChildFill="False">
<TextBlock Text="{Binding TabText}" DockPanel.Dock="Left" />
<Button x:Name="TabCloseButton" Click="TabCloseButton_Click" DockPanel.Dock="Right" >
<Button.Template>
<ControlTemplate TargetType="Button">
<materialDesign:PackIcon
Kind="Close" Foreground="White"
VerticalAlignment="Center" HorizontalAlignment="Center"
Width="20" Height="20" />
</ControlTemplate>
</Button.Template>
</Button>
</DockPanel>
</DataTemplate>
</Window.Resources>
<Grid>
<ListView
ItemsSource="{Binding TabItems}"
ItemTemplate="{StaticResource TabListViewItemTemplate}"
HorizontalContentAlignment="Stretch"
/>
</Grid>
MainWindow.xaml.cs
public MainWindow()
{
InitializeComponent();
DataContext = new MainViewModel
{
TabItems = {
new TabData { TabText = "Fred" },
new TabData { TabText = "Ginger" },
new TabData { TabText = "Herman" },
}
};
}
private void TabCloseButton_Click(object sender, RoutedEventArgs e)
{
if ((sender as FrameworkElement).DataContext is TabData tabData)
{
MessageBox.Show($"TabCloseButton_Click() {tabData.TabText}");
}
}
TabData類。 不要繼承UIElement。 它不是用戶界面中的元素,只是一個普通的C#類。 如果要讓用戶編輯TabText,則將其設為實現INotifyPropertyChanged的視圖模型。
public class TabData
{
public string TabText { get; set; }
}
主視圖模型。 實際上,我們在這里所做的任何事情實際上都不需要在您的任何類上使用INotifyPropertyChanged,但是如果您將其轉換為有用的東西,則將需要它,因此我們將其包含在內。
public class ViewModelBase : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([System.Runtime.CompilerServices.CallerMemberName] string propName = null) =>
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propName));
}
public class MainViewModel : ViewModelBase
{
public ObservableCollection<TabData> TabItems { get; } = new ObservableCollection<TabData>();
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.