编写一段Csharp语言 用于wpf中创建一个可折叠列表 列表包含文件名、用户名、时间 列表数据通过mvvm模式绑定 并且用按钮可以切换按用户名折叠还是按文件名折叠
时间: 2023-06-05 10:07:43 浏览: 285
很高兴为您解答问题!以下是您要求的 C# 代码:
首先,我们需要先创建一个 Model 层,定义列表信息:
```
public class ListItem
{
public string FileName { get; set; }
public string UserName { get; set; }
public DateTime Time { get; set; }
}
```
接着,我们需要创建一个 ViewModel 层,用于处理业务逻辑和数据绑定:
```
public class ListViewModel : INotifyPropertyChanged
{
private ObservableCollection<ListItem> _list;
private bool _isUserNameFolded = true;
public ObservableCollection<ListItem> List
{
get => _list;
set
{
if (_list != value)
{
_list = value;
OnPropertyChanged(nameof(List));
}
}
}
public bool IsUserNameFolded
{
get => _isUserNameFolded;
set
{
if (_isUserNameFolded != value)
{
_isUserNameFolded = value;
OnPropertyChanged(nameof(IsUserNameFolded));
UpdateList();
}
}
}
public ListViewModel()
{
// 初始化列表数据
List = new ObservableCollection<ListItem>
{
new ListItem { FileName = "file1", UserName = "user1", Time = DateTime.Now },
new ListItem { FileName = "file2", UserName = "user2", Time = DateTime.Now.AddDays(-1) },
new ListItem { FileName = "file3", UserName = "user3", Time = DateTime.Now.AddDays(-2) },
new ListItem { FileName = "file4", UserName = "user4", Time = DateTime.Now.AddDays(-3) }
};
UpdateList();
}
private void UpdateList()
{
if (IsUserNameFolded)
{
// 按用户名折叠
var group = List.GroupBy(x => x.UserName).Select(x => new
{
Key = x.Key,
Items = x.ToList()
});
var result = new ObservableCollection<ListItem>();
foreach (var g in group)
{
result.Add(new ListItem
{
FileName = $"{g.Key} ({g.Items.Count})",
UserName = g.Key,
Time = g.Items.OrderByDescending(x => x.Time).First().Time
});
}
List = result;
}
else
{
// 按文件名折叠
var group = List.GroupBy(x => x.FileName).Select(x => new
{
Key = x.Key,
Items = x.ToList()
});
var result = new ObservableCollection<ListItem>();
foreach (var g in group)
{
result.Add(new ListItem
{
FileName = g.Key,
UserName = $"{g.Items.Select(x => x.UserName).Distinct().Count()} users",
Time = g.Items.OrderByDescending(x => x.Time).First().Time
});
}
List = result;
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
```
然后,我们需要创建一个 View 层,用于显示界面和与用户交互:
```
<Window x:Class="WpfApp1.MainWindow"
DataContext="{Binding RelativeSource={RelativeSource Self}}"
Title="MainWindow" Height="450" Width="800">
<Window.Resources>
<DataTemplate x:Key="ListItemTemplate">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding UserName}" Margin="5"/>
<TextBlock Text="{Binding FileName}" Margin="5"/>
<TextBlock Text="{Binding Time}" Margin="5"/>
</StackPanel>
</DataTemplate>
</Window.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition/>
</Grid.RowDefinitions>
<StackPanel Orientation="Horizontal" Margin="5">
<Button Content="按用户名折叠" Margin="5" Command="{Binding FoldByUserNameCommand}"/>
<Button Content="按文件名折叠" Margin="5" Command="{Binding FoldByFileNameCommand}"/>
</StackPanel>
<ListView Grid.Row="1" ItemsSource="{Binding List}" ItemTemplate="{StaticResource ListItemTemplate}"
Margin="5" BorderThickness="1" BorderBrush="Gray">
</ListView>
</Grid>
</Window>
```
最后,在代码中实现页面逻辑:
```
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
DataContext = new ListViewModel();
}
}
```
对于按用户名折叠和按文件名折叠的操作,我们通过绑定按钮的 Command 属性来实现,在 ViewModel 中定义了对应的命令处理逻辑:
```
public class RelayCommand : ICommand
{
private readonly Action _execute;
private readonly Func<bool> _canExecute;
public RelayCommand(Action execute, Func<bool> canExecute = null)
{
_execute = execute;
_canExecute = canExecute;
}
public bool CanExecute(object parameter)
{
return _canExecute == null || _canExecute();
}
#pragma warning disable 67
public event EventHandler CanExecuteChanged;
#pragma warning restore 67
public void Execute(object parameter)
{
_execute?.Invoke();
}
}
public class ListViewModel : INotifyPropertyChanged
{
// ...
public ICommand FoldByUserNameCommand => new RelayCommand(() =>
{
IsUserNameFolded = true;
}, () => !IsUserNameFolded);
public ICommand FoldByFileNameCommand => new RelayCommand(() =>
{
IsUserNameFolded = false;
}, () => IsUserNameFolded);
// ...
}
```
希望这段代码能够对您有所帮助!
阅读全文