我正在学习WPF并试图遵循某种最佳实践。我此刻有点失落,需要一些指导。
我正在创建一个非常简单的应用程序,它读取文本文件(错误日志)并将其拆分为单独的错误消息。我想将这些消息(存储在模型对象中)显示为消息列表。由于列表可以包含许多项目,并且我希望窗口可以调整大小,我需要一个垂直滚动条,但我希望内容包装(即不需要水平滚动条)。
<Window x:Class="ErrorLog.UI.WPF.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="800" Width="1200" Loaded="Window_Loaded">
<StackPanel Name="mainContainer">
<StackPanel Orientation="Horizontal" Name="Menu">
<Button Name="Refresh">Refresh</Button>
</StackPanel>
<ScrollViewer VerticalScrollBarVisibility="Auto">
<StackPanel Name="errorMessagePlaceHolder"></StackPanel>
</ScrollViewer>
</StackPanel>
我正在读取后面代码中的文件,并将stackPanel添加到一堆文本框中,其值为错误消息。我还添加了一些像这样的鼠标悬停效果:
private void LoadData()
{
IErrorLogReader errorLogReader = new ErrorLogReader();
var errors = errorLogReader.RetrieveErrors();
if (errors.Count == 0)
{
TextBox noErrors = new TextBox();
noErrors.Text = "No errors found";
errorMessagePlaceHolder.Children.Add(noErrors);
}
else
{
for (var i = errors.Count - 1; i > 0; i--)
{
TextBox errorMessage = new TextBox();
errorMessage.IsReadOnly = true;
errorMessage.Padding = new Thickness(10);
errorMessage.Text = errors[i].ErrorMessage;
errorMessage.TextWrapping = TextWrapping.Wrap;
errorMessage.MouseEnter += ErrorMessageMouseEnter;
errorMessage.MouseLeave += ErrorMessageMouseLeave;
errorMessagePlaceHolder.Children.Add(errorMessage);
}
}
}
protected void ErrorMessageMouseEnter(object sender, RoutedEventArgs e)
{
((TextBox) sender).Background = Brushes.AntiqueWhite;
}
protected void ErrorMessageMouseLeave(object sender, RoutedEventArgs e)
{
((TextBox) sender).Background = null;
}
所以我想知道的第一件事是:
干杯。
答案 0 :(得分:2)
我绑定的方式好吗?
它可能会奏效,但这不是最佳做法。最佳实践是使用实际数据绑定。首先,您需要将StackPanel替换为可绑定到列表的内容。 ItemsControl
是最接近简单StackPanel的东西,其他选项例如是ListBox。
<ScrollViewer VerticalScrollBarVisibility="Auto">
<ItemsControl Name="errorMessageList" />
</ScrollViewer>
private void LoadData()
{
IErrorLogReader errorLogReader = new ErrorLogReader();
var errors = errorLogReader.RetrieveErrors();
errorMessageList.ItemsSource = errors;
}
要指定 如何显示错误消息,您可以为ItemsControl设置模板:
<ScrollViewer VerticalScrollBarVisibility="Auto">
<ItemsControl Name="errorMessageList">
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBox IsReadOnly="true" ... Text="{Binding ErrorMessage}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
滚动条即将停用
您正在将ScrollViewer嵌套在StackPanel中......这将无效:StackPanel需要尽可能多的垂直空间,因此ScrollViewer 总是有足够的空间并且从不显示滚动条。您需要用一个只占用可用空间的空间来替换您的顶级StackPanel;一个DockPanel,例如:
<DockPanel Name="mainContainer">
<StackPanel DockPanel.Dock="Top" Orientation="Horizontal" Name="Menu">
<Button Name="Refresh">Refresh</Button>
</StackPanel>
<ScrollViewer VerticalScrollBarVisibility="Auto">
<StackPanel Name="errorMessagePlaceHolder"></StackPanel>
</ScrollViewer>
</StackPanel>
我做鼠标悬停效果的方式不好吗?
可以使用样式和触发器来完成。定义以下样式:
<Window ...>
<Window.Resources>
<Style x:Key="hoverTextBox" TargetType="{x:Type TextBox}">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="AntiqueWhite" />
</Trigger>
</Style.Triggers>
</Style>
</Window.Resources>
...
</Window>
并将其分配给DataTemplate中的TextBox:
<TextBox IsReadOnly="true" ... Text="{Binding ErrorMessage}"
Style="{StaticResource hoverTextBox}" />