2010-12-01 11 views
2

ich WPF lerne und ich versuche, eine Art Best-Practice zu folgen. Ich bin im Moment irgendwie verloren und brauche eine Richtung.Grund WPF-Layout Frage

Ich habe eine sehr einfache Anwendung, erschaffe, die eine Textdatei (Fehlerprotokoll) liest und teilt sie in den einzelnen Fehlermeldungen. Ich möchte diese Nachrichten (die in einem Modellobjekt gespeichert sind) als eine Liste von Nachrichten anzeigen. Da die Liste aus vielen Elementen bestehen kann und das Fenster in der Größe veränderbar sein soll, brauche ich eine vertikale Bildlaufleiste, aber ich möchte, dass der Inhalt umgebrochen wird (d. H. Keine horizontale Bildlaufleiste benötigt wird).

<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> 

ich im Moment bin Nachricht die Datei im Code hinter und zur Ergänzung der Stackpanel als ein Bündel von Textbox mit wobei der Wert der Fehler zu lesen. Ich habe auch ein paar Mouseover-Effekte wie folgt hinzugefügt:

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; 
    } 

So sind die ersten Dinge, die ich wissen möchte, ist:

  • Ist die Art, wie ich ok bin verbindlich?
  • Bildlaufleiste wird deaktiviert
  • Ist die Art, wie ich den mouseover Effekt mache schlecht?

Beifall.

Antwort

2

Ist die Art, wie ich ok bin verbindlich?

Es könnte funktionieren, aber es ist nicht Best Practice. Es empfiehlt sich, die tatsächliche Datenbindung zu verwenden. Zuerst müssen Sie Ihr StackPanel durch etwas ersetzen, das an eine Liste gebunden werden kann. Ein ItemsControl ist die Sache, die einem einfachen StackPanel am nächsten kommt, andere Optionen wären zum Beispiel eine ListBox.

<ScrollViewer VerticalScrollBarVisibility="Auto"> 
    <ItemsControl Name="errorMessageList" /> 
</ScrollViewer> 
private void LoadData() 
{ 
    IErrorLogReader errorLogReader = new ErrorLogReader(); 
    var errors = errorLogReader.RetrieveErrors(); 

    errorMessageList.ItemsSource = errors; 
} 

So gibt wie Sie die Fehlermeldungen angezeigt werden sollen, können Sie eine Vorlage für das Item einstellen:

<ScrollViewer VerticalScrollBarVisibility="Auto"> 
    <ItemsControl Name="errorMessageList"> 
     <ItemsControl.ItemTemplate> 
      <DataTemplate> 
       <TextBox IsReadOnly="true" ... Text="{Binding ErrorMessage}" /> 
      </DataTemplate> 
     </ItemsControl.ItemTemplate> 
    </ItemsControl> 
</ScrollViewer> 

Bildlaufleiste ist Auftauchen deaktiviert

Sie nisten Ihre Scroll in einem Stackpanel ... das wird nicht funktionieren: Die Stackpanel nimmt so viel vertikalen Raum, wie es braucht, so dass die Scroll wird immer haben genug Platz und zeigen nie die Bildlaufleiste. Sie benötigen eine Top-Level-Stackpanel durch etwas zu ersetzen, die nur so viel Platz in Anspruch nimmt als verfügbar ist; ein DockPanel, zum Beispiel:

<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> 

Ist die Art, wie ich schlecht den Mouseover-Effekt mache?

Das kann mit einem Stil und einem Auslöser stattdessen getan werden. Definieren Sie die folgenden Stil:

<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> 

und weisen Sie auf Ihre TextBox innerhalb der Datatemplate:

<TextBox IsReadOnly="true" ... Text="{Binding ErrorMessage}" 
     Style="{StaticResource hoverTextBox}" /> 
+0

Vielen Dank dafür. Hat mir geholfen, Haufen. –