亲爱的开发者,这是美好的一天 我的名字是丹尼.
这是我在Stackoverflow上发表的第一篇文章......尽管我对.NET Framework很新.我通过几个论坛进行了相当彻底的搜索,但显然是我的鼻子.
我的问题是:我正在编写一段脚本,读出目录中存在多少.txt文件.
然后它创建了GroupBoxes(每个网格)的数量,因为.txt是通过'foreach'命令.在同一个foreach-command中,我使用:Grid.Children.Add(control).每次迭代时,有2个控件要添加到生成的网格中.
问题:它没有那样做......好吧.它只进行了2次迭代,无论有多少.txt.在输出对话框中,它说:A first chance exception of type 'System.ArgumentException' occurred in PresentationCore.dll.
如果我的解释不像我想的那样清楚,请按照我的脚本,并感谢阅读:
using System;
using System.IO;
using System.Linq;
using System.Windows;
using System.Threading;
using System.Windows.Media;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Threading;
using System.Windows.Controls.Primitives;
namespace Notes
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
// Create Objects
public TextBox tBox = new TextBox();
public Label fLabel = new Label();
public GroupBox group = new GroupBox();
public Grid groupGrid = new Grid();
private void Window_Loaded(object sender, RoutedEventArgs e)
{
// Global Variables
int Increment = 1;
string Dir = "DIRECTORY_HERE";
int leftMargin = 10;
int betweenMargin = 10;
// GroupBox Initials
group.Height = this.Height - 125;
group.Margin = new Thickness(0, 75, 0, 0);
group.HorizontalAlignment = HorizontalAlignment.Left;
group.VerticalAlignment = VerticalAlignment.Top;
// Grid Initials
groupGrid.Width = leftMargin;
groupGrid.Height = group.Height;
groupGrid.Margin = new Thickness(0, 0, 0, 0);
groupGrid.HorizontalAlignment = HorizontalAlignment.Left;
groupGrid.VerticalAlignment = VerticalAlignment.Top;
// Label Initials
fLabel.Width = 260;
fLabel.Height = 28;
fLabel.HorizontalAlignment = HorizontalAlignment.Left;
fLabel.VerticalAlignment = VerticalAlignment.Top;
fLabel.Margin = new Thickness(0, 0, 0, 0);
// TextBox Intitials
tBox.Width = 100;
tBox.Height = groupGrid.Height;
tBox.VerticalScrollBarVisibility = ScrollBarVisibility.Hidden;
tBox.HorizontalAlignment = HorizontalAlignment.Left;
tBox.VerticalAlignment = VerticalAlignment.Top;
tBox.Foreground = new SolidColorBrush(Colors.DarkCyan);
tBox.Background = new SolidColorBrush(Colors.Red);
tBox.TextWrapping = TextWrapping.NoWrap;
// Get paths of all files within given directory.
string[] Notes = Directory.GetFiles(Dir, "*.*", SearchOption.TopDirectoryOnly).ToArray();
foreach (string Note in Notes)
{
Console.WriteLine("NOTE: " + Note);
// Text settings
FileInfo fi = new FileInfo(Note);
TextReader tr = new StreamReader(fi.ToString());
tBox.Name = "tBox" + Increment.ToString();
tBox.Text = tr.ReadToEnd();
tBox.Margin = new Thickness(betweenMargin, 0, 0, 0);
// FileLabel settings
fLabel.Name = "fLabel" + Increment.ToString();
// GroupGrid settings
groupGrid.Name = "groupGrid" + Increment.ToString();
groupGrid.Children.Add(tBox); //error
groupGrid.Children.Add(fLabel); //error
// group settings
group.Width = leftMargin + (tBox.Width * Increment) + (betweenMargin * Increment);
group.Content = groupGrid;
// Increment
Increment++;
}
NotesDoc.Children.Add(group);
}
Run Code Online (Sandbox Code Playgroud)
小智 5
您正在尝试像编写Windows窗体应用程序一样编写WPF应用程序.相信我,如果您真正学习了一些WPF开发模式(例如MVVM),那么您可以更轻松地实现目标.
例如,使用ObservableCollection可以很容易地完成此操作(保存所有这些)(不确定如何执行此操作)FileInfo实例(每个文件一个).
然后,您可以绑定一个ItemsControl中的的ItemsSource属性来此集合.现在,每当您向ObservableCollection添加新的FileInfo实例时,ItemsControl将添加一个新行并将该行绑定到该实例.
当然,每行的默认模板只是在每个实例上调用.ToString(),因此您将获得包含"System.IO.FileInfo"的一堆行.要显示有关每个FileInfo的信息,可以将DataTemplate添加到ItemsSource.ItemTemplate并添加绑定到FileInfo的公共属性的控件.
在开发WPF应用程序时,了解其中一些基本模式非常重要.尝试以您正在尝试的方式从代码隐藏中与UI进行交互是非常难做的.WPF应用程序的许多UI模式都经过优化,可用于XAML; 尝试与代码隐藏中的这些(例如附加属性)进行交互可能会非常混乱和违反直觉.
这是我更新的一个简单的MVVM示例.要使用它,请创建一个名为SimpleMVVM的新解决方案(3.5或更高版本).在项目的根目录中创建一个名为ViewModel的新类,并将以下代码添加到该文件中:
/// <summary>
/// A simple ViewModel to demonstrate MVVM
/// </summary>
public sealed class ViewModel : DependencyObject, IDataErrorInfo
{
#region Properties
#region DirectoryName
/// <summary>
/// The <see cref="DependencyProperty"/> for <see cref="DirectoryName"/>.
/// </summary>
public static readonly DependencyProperty DirectoryNameProperty =
DependencyProperty.Register(
DirectoryNameName,
typeof(string),
typeof(ViewModel),
new UIPropertyMetadata(null));
/// <summary>
/// The name of the <see cref="DirectoryName"/> <see cref="DependencyProperty"/>.
/// </summary>
public const string DirectoryNameName = "DirectoryName";
/// <summary>
///
/// </summary>
public object DirectoryName
{
get { return (object)GetValue(DirectoryNameProperty); }
set { SetValue(DirectoryNameProperty, value); }
}
#endregion
#region SelectedFile
/// <summary>
/// The <see cref="DependencyProperty"/> for <see cref="SelectedFile"/>.
/// </summary>
public static readonly DependencyProperty SelectedFileProperty =
DependencyProperty.Register(
SelectedFileName,
typeof(FileInfo),
typeof(ViewModel),
new UIPropertyMetadata(null));
/// <summary>
/// The name of the <see cref="SelectedFile"/> <see cref="DependencyProperty"/>.
/// </summary>
public const string SelectedFileName = "SelectedFile";
/// <summary>
///
/// </summary>
public FileInfo SelectedFile
{
get { return (FileInfo)GetValue(SelectedFileProperty); }
set { SetValue(SelectedFileProperty, value); }
}
#endregion
/// <summary>
/// The files found under <see cref="DirectoryName"/>.
/// </summary>
public ObservableCollection<FileInfo> Files { get; private set; }
/// <summary>
/// Holds the last filename error for IDataErrorInfo
/// </summary>
private string _lastDirectoryNameError = null;
#endregion
#region ctor
/// <summary>
/// Initializes a new instance of the <see cref="ViewModel"/> class.
/// </summary>
public ViewModel()
{
Files = new ObservableCollection<FileInfo>();
}
#endregion
#region methods
/// <summary>
/// Invoked whenever the effective value of any dependency property on this <see cref="T:System.Windows.DependencyObject"/> has been updated. The specific dependency property that changed is reported in the event data.
/// </summary>
/// <param name="e">Event data that will contain the dependency property identifier of interest, the property metadata for the type, and old and new values.</param>
protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e)
{
base.OnPropertyChanged(e);
if (e.Property == DirectoryNameProperty)
UpdateFiles(e.OldValue as string, e.NewValue as string);
}
/// <summary>
/// Updates <see cref="Files"/> when <see cref="DirectoryName"/> changes.
/// </summary>
/// <param name="oldDirectoryName">The old value of <see cref="DirectoryName"/></param>
/// <param name="newDirectoryName">The new value of <see cref="DirectoryName"/></param>
private void UpdateFiles(string oldDirectoryName, string newDirectoryName)
{
if (string.IsNullOrWhiteSpace(newDirectoryName))
{
Files.Clear();
return;
}
if (!string.IsNullOrEmpty(oldDirectoryName) &&
oldDirectoryName.Equals(newDirectoryName, StringComparison.OrdinalIgnoreCase))
return;
try
{
var di = new DirectoryInfo(Directory.Exists(newDirectoryName) ? newDirectoryName : Path.GetDirectoryName(newDirectoryName));
// dirty hack
if (di.ToString().Equals(".", StringComparison.OrdinalIgnoreCase))
{
_lastDirectoryNameError = "Not a valid directory name.";
return;
}
Files.Clear();
foreach (var file in di.GetFiles())
Files.Add(file);
_lastDirectoryNameError = null;
}
catch (Exception ioe)
{
_lastDirectoryNameError = ioe.Message;
}
}
#endregion
#region IDataErrorInfo
/// <summary>
/// Gets an error message indicating what is wrong with this object.
/// </summary>
/// <returns>An error message indicating what is wrong with this object. The default is an empty string ("").</returns>
string IDataErrorInfo.Error
{
get
{
return _lastDirectoryNameError;
}
}
/// <summary>
/// Gets the error message for the property with the given name.
/// </summary>
/// <returns>The error message for the property. The default is an empty string ("").</returns>
string IDataErrorInfo.this[string columnName]
{
get
{
if (columnName.Equals(DirectoryNameName, StringComparison.OrdinalIgnoreCase))
return _lastDirectoryNameError;
return null;
}
}
#endregion
}
Run Code Online (Sandbox Code Playgroud)
接下来,打开MainWindow.xaml并使用以下内容替换xaml:
<Window
x:Class="SimpleMVVM.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:t="clr-namespace:SimpleMVVM"
Title="MainWindow"
Height="350"
Width="525">
<Window.DataContext>
<t:ViewModel />
</Window.DataContext>
<Window.Resources>
<Style
x:Key="alternatingListViewItemStyle"
TargetType="{x:Type ListViewItem}">
<Style.Triggers>
<Trigger
Property="ItemsControl.AlternationIndex"
Value="1">
<Setter
Property="Background"
Value="LightGray"></Setter>
</Trigger>
<Trigger
Property="ItemsControl.AlternationIndex"
Value="2">
<Setter
Property="Background"
Value="White"></Setter>
</Trigger>
</Style.Triggers>
</Style>
</Window.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition
Height="auto" />
<RowDefinition />
<RowDefinition
Height="auto" />
</Grid.RowDefinitions>
<TextBox
Margin="4"
Text="{Binding DirectoryName, ValidatesOnDataErrors=True, ValidatesOnExceptions=True,UpdateSourceTrigger=PropertyChanged}">
<TextBox.Style>
<Style
TargetType="TextBox">
<Setter
Property="ToolTip"
Value="Please enter a directory name" />
<Style.Triggers>
<Trigger
Property="Validation.HasError"
Value="true">
<Setter
Property="ToolTip"
Value="{Binding (Validation.Errors)[0].ErrorContent, RelativeSource={x:Static RelativeSource.Self}}" />
</Trigger>
</Style.Triggers>
</Style>
</TextBox.Style>
</TextBox>
<ListView
Margin="4"
Grid.Row="1"
AlternationCount="2"
ItemsSource="{Binding Files}"
ItemContainerStyle="{StaticResource alternatingListViewItemStyle}"
SelectedItem="{Binding SelectedFile}">
<ListView.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition
Width="100" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Label
Grid.Row="0">Name</Label>
<Label
Grid.Row="1">Size</Label>
<Label
Grid.Row="2">Read Only</Label>
<Label
Grid.Row="3">Type</Label>
<TextBlock
Grid.Row="0"
Grid.Column="1"
Text="{Binding Name}" />
<TextBlock
Grid.Row="1"
Grid.Column="1"
Text="{Binding Length}" />
<CheckBox
Grid.Row="2"
Grid.Column="1"
IsChecked="{Binding IsReadOnly}"
IsEnabled="False" />
<TextBlock
Grid.Row="3"
Grid.Column="1"
Text="{Binding Extension}" />
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<StatusBar
Grid.Row="2">
<StatusBarItem
Content="{Binding SelectedFile.FullName, StringFormat='Selected: {0}', FallbackValue='Please enter a directory and select a file.'}" />
</StatusBar>
</Grid>
</Window>
Run Code Online (Sandbox Code Playgroud)
(请原谅每个人的代码转储!)编译,修复错误并运行它.
| 归档时间: |
|
| 查看次数: |
2729 次 |
| 最近记录: |