2010-12-01 88 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