2010-12-01 55 views
2

我正在学习WPF,并试图遵循某种最佳实践。我现在有点迷路,需要一些指导。基本的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; 
    } 

所以第一件事情我想知道的是:

  • 是我绑定确定的方式吗?
  • 滚动条即将被禁用
  • 我在做mouseover效果的方式不好吗?

干杯。

回答

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 IsReadOnly="true" ... Text="{Binding ErrorMessage}" 
     Style="{StaticResource hoverTextBox}" /> 
+0

感谢您的。帮助我堆积如山。 – 2010-12-01 03:56:58