【发布时间】:2020-04-20 12:16:44
【问题描述】:
我想在单选按钮上选择的文件夹下显示文件名。但是,我的程序仅显示 last 文件夹下的文件名。即使更改了选择,文件名也不会更改。
我尝试了一些 LINQ 语句,但没有一个有效。我怎样才能解决这个问题?这是我的完整代码:
编辑:缩短代码并添加 Show_Button_Click()
MainWindow.xaml.cs
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Windows;
using System.Windows.Controls;
namespace Folder_Reader
{
public class Question
{
public string QuestType { get; set; }
public string Label { get; set; }
public ObservableCollection<Answer> Answers { get; set; }
}
public class Answer : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private void RaisePropertyChanged([CallerMemberName]string propertyName = null)
=> PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
private string _Ans;
public string Ans
{
get => _Ans;
set
{
if (_Ans == value)
return;
_Ans = value;
RaisePropertyChanged();
RaisePropertyChanged(nameof(FullName));
}
}
public string FullName => $"{Ans}";
public bool IsSelected { get; set; }
}
public partial class MainWindow : Window
{
public ObservableCollection<Question> Questions { get; set; }
List<string> ToBeMergedList = new List<string>();
public static readonly DependencyProperty QuestionProperty =
DependencyProperty.Register("Question", typeof(Question), typeof(MainWindow),
new FrameworkPropertyMetadata((Question)null));
public Question Question
{
get { return (Question)GetValue(QuestionProperty); }
set { SetValue(QuestionProperty, value); }
}
public MainWindow()
{
InitializeComponent();
RunMerge();
}
private void RunMerge()
{
string dataPath = @"C:\Data\";
DirectoryInfo[] folders = GetFoldernames(dataPath);
FillInClass();
string typePath = null;
StringBuilder sb = new StringBuilder();
foreach (var (q, toBeSelectedFolder) in from q in Questions
from toBeSelectedFolder in folders
select (q, toBeSelectedFolder))
{
sb.AppendLine($"{ toBeSelectedFolder }");
q.Answers.Add(new Answer() { Ans = toBeSelectedFolder.ToString() });
// This line finally puts the LAST folder into typePath, but I don't know how to fix this
typePath = toBeSelectedFolder.FullName.ToString();
//typePath = q.Answers.Where(a => a.IsSelected).Select(a => a.Ans).ToString();
}
DataContext = this;
string searchPattern = "*log*.xlsx";
FileInfo[] files = GetFilenames(typePath, searchPattern);
List<Datalog> DatalogList = new List<Datalog>();
AddDatalogList(DatalogList, files);
MyListView.ItemsSource = DatalogList;
}
private void FillInClass()
{
Questions = new ObservableCollection<Question>()
{
new Question()
{
QuestType = "Radio",
Label = "Type",
Answers = new ObservableCollection<Answer>()
}
};
}
private static DirectoryInfo[] GetFoldernames(string path)
{
DirectoryInfo di = new DirectoryInfo(path);
DirectoryInfo[] folders =
di.GetDirectories("*", SearchOption.TopDirectoryOnly);
return folders;
}
private static FileInfo[] GetFilenames(string path, string searchPattern)
{
DirectoryInfo di = new DirectoryInfo(path);
FileInfo[] files =
di.GetFiles(searchPattern, SearchOption.AllDirectories);
return files;
}
private static void AddDatalogList(List<Datalog> DatalogList, FileInfo[] files)
{
var duplicateGroups = files.GroupBy(file => file.Name)
.Where(group => group.Count() > 1);
foreach (var group in duplicateGroups)
{
DatalogList.Add(new Datalog() { Merge = false, Filename = group.First().FullName });
}
var singleGroups = files.GroupBy(file => file.Name)
.Where(group => group.Count() == 1);
foreach (var group in singleGroups)
{
foreach (var file in group)
{
DatalogList.Add(new Datalog() { Merge = false, Filename = file.FullName });
}
}
}
private void CheckBox_Checked(object sender, RoutedEventArgs args)
{
ToBeMergedList.Add((sender as CheckBox).Content.ToString());
}
private void CheckBox_Unchecked(object sender, RoutedEventArgs args)
{
ToBeMergedList.Remove((sender as CheckBox).Content.ToString());
}
private void Show_Button_Click(object sender, RoutedEventArgs e)
{
foreach (Question q in Questions)
{
Console.WriteLine(q.Label + " : "
+ string.Join(", ", q.Answers.Where(a => a.IsSelected).Select(a => a.Ans)));
MessageBox.Show(q.Label + " : "
+ string.Join(", ", q.Answers.Where(a => a.IsSelected).Select(a => a.Ans)));
}
}
private void Merge_Button_Click(object sender, RoutedEventArgs e)
{
StringBuilder sb = new StringBuilder();
foreach (var toBeMergedFile in ToBeMergedList)
{
sb.AppendLine($"{ toBeMergedFile }");
}
MessageBox.Show(sb.ToString());
}
}
}
MainWindow.xaml
<Window x:Class="Folder_Reader.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:Folder_Reader"
mc:Ignorable="d"
Title="Merge Tool" Height="500" Width="450">
<Window.Resources>
<DataTemplate x:Key="RadioQuestion">
<ItemsControl ItemsSource="{Binding Answers}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<RadioButton Content="{Binding Ans}" IsChecked="{Binding IsSelected, Mode=TwoWay}"
GroupName="{Binding DataContext.Label,
RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</DataTemplate>
</Window.Resources>
<Grid RenderTransformOrigin="0.5,0.5">
<Grid.RowDefinitions>
<RowDefinition Height="150*"/>
<RowDefinition Height="421*"/>
</Grid.RowDefinitions>
<Border BorderThickness="2">
<ScrollViewer VerticalScrollBarVisibility="Auto" Margin="10,0,0,0">
<StackPanel>
<ItemsControl ItemsSource="{Binding Questions}" Grid.IsSharedSizeScope="True">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" SharedSizeGroup="Label"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding Label}"/>
<ContentControl x:Name="ccQuestion" Grid.Column="1"
Content="{Binding}" Margin="10"/>
</Grid>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding QuestType}" Value="Radio">
<Setter TargetName="ccQuestion" Property="ContentTemplate"
Value="{StaticResource RadioQuestion}"/>
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>
</ScrollViewer>
</Border>
<ListView HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
Name="MyListView" Margin="0,0,0,40" Grid.Row="1">
<ListView.View>
<GridView>
<GridViewColumn Header="To-Be-Merged File">
<GridViewColumn.CellTemplate>
<DataTemplate>
<CheckBox Margin="5,0" IsChecked="{Binding Merge}" Content="{Binding Filename}"
Checked="CheckBox_Checked" Unchecked="CheckBox_Unchecked"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
<Button Content="Show" HorizontalAlignment="Right" VerticalAlignment="Bottom"
Margin="0,0,252.2,10.4" Width="100" Click="Show_Button_Click" Grid.Row="1" Height="21"/>
<Button Content="Merge" HorizontalAlignment="Right" VerticalAlignment="Bottom"
Margin="0,0,73.6,10.4" Width="100" Click="Merge_Button_Click" Grid.Row="1" Height="21"/>
</Grid>
</Window>
Datalog.cs
namespace Folder_Reader
{
public class Datalog
{
public bool Merge { get; set; }
public string Filename { get; set; }
}
}
假设有三个文件夹:
- 文件夹 A 包含 1_log.xlsx、2_log.xlsx、3_log.xlsx
- FolderB 包含 4_log.xlsx、5_log.xlsx、6_log.xlsx
- 文件夹 C 包含 7_log.xlsx、8_log.xlsx、9_log.xlsx。
在这种情况下,即使选择了 FolderA,也会显示 7_、8_、9_log.xlsx。当我在单选按钮上选择 FolderA 时,我希望看到 1_、2_、3_log.xlsx。
【问题讨论】:
-
好的,据我所知,您在最后一段中尝试显示文件夹和此文件夹中的所有文件。对吗?为了清楚起见,我省略了所有这些 win 表单的具体细节
-
@QwertyQwerty:你说得对,我试图显示所选文件夹中的所有文件。
-
@IanHacker:由于您只调用一次
RunMerge(),在构造函数中,您希望在选择单选按钮时如何执行它?您的代码没有多大意义。为什么不先填充要从中选择的文件夹,然后处理选择? -
@mm8:(如果我错了,请阻止我,但是)我想我已经做到了。
Answer类派生自INotifyPropertyChanged,因此每次更改 Radio-Button 选择时,都会将更改反映到实例Answers。我刚刚添加了一次删除的方法Show_Button_Click()。请选择FolderB并点击Show。 -
@IanHacker:你认为你做了什么?那么我的第一个问题呢?
标签: c# wpf linq radio-button