2016-04-19 6 views
3

neu geschriebenHandhabung Styling mit Datenbindung

Ich habe eine Anwendung, die eine Datei empfängt. Diese Datei enthält viele bearbeitbare Inhalte. Dieser Inhalt kommt in einer Vielzahl von möglichen Typen (d. H. Boolesche Ankreuzfelder, Textfelder usw.). Das Problem ist, dass diese Werte entweder allein oder in einer Gruppe (bis zu 8) sein können, also kommen sie in Arrays. Wir binden diese Werte an eine ListView und verwenden DataTemplates, um sie anzuzeigen. Effektiv erstelle ich die ListView aus einer Liste von Arrays.

Die Elemente in diesen Arrays müssen datengebunden und ordnungsgemäß formatiert sein (z. B. muss ein boolesches Array Kontrollkästchen erstellen, während ein Zeichenfolgenarray Textfelder benötigt). Jedes erstellte Element muss in eine Spalte in der ListView eingefügt werden. Das aktuelle Styling verwendet DataTemplates mit Datenbindung, dh

<DataTemplate x:Key="testTemplate2"> 
    <TextBlock Text="{Binding Path=Value[0]}" 
       Margin="2" 
       HorizontalAlignment="Center" 
       VerticalAlignment="Center" /> 
</DataTemplate> 

dies für jeden Wert in dem Eingangsfeld wiederholt wird, so dass man Value[1], Value[2] usw.

Das bedeutet, fast den gleichen Code Wiederholen 8 Zeiten, und dann das Gleiche für den nächsten Typ. Da es eine große Anzahl von Eingabetypen gibt, bedeutet dies eine lächerliche Menge an wiederholtem Code.

Meine Frage ist: Gibt es eine bessere Möglichkeit, dies zu tun, so dass wir Datenvorlagen nicht wiederholen müssen, während Spalten verwenden?

Übrigens benutze ich .NET 3.5.

Beispiel, wie eine Zeile aussehen würde. Jedes Element würde in einer eigenen Spalte stehen. Die Comboboxen werden aus dem Array erstellt. Example of what I want.

EDIT Beispiel Datatemplate:

<DataTemplate x:Key="textBoxTemplate2"> 
    <TextBox Text="{Binding Path=Value[2], NotifyOnSourceUpdated=True, UpdateSourceTrigger=PropertyChanged}" 
        BorderBrush="{DynamicResource ComboBorder}" 
        Tag="{Binding Path=AllowedChars}" 
        PreviewTextInput="PreviewTextInputHandler" 
        DataObject.Pasting="PastingHandler" 
        ToolTip="{Binding Path=Title}" 
        Margin="2" 
        SourceUpdated="BindingSourceUpdated" 
        MaxLength="{Binding Path=DataLength}" 
        HorizontalAlignment="Stretch" 
        VerticalAlignment="Center" > 
     <TextBox.IsEnabled> 
      <MultiBinding Converter="{StaticResource isEnabledConverter}"> 
       <Binding Path="IsLocked" Mode="OneWay" /> 
       <Binding Path="IsVisible[2]" Mode="OneWay" /> 
      </MultiBinding> 
     </TextBox.IsEnabled> 
    </TextBox> 
</DataTemplate> 

Beispiel Diagramm:

Diagram

Ich habe ein Ansichtsmodell. Dieses ViewModel hat eine Liste, die aus ItemData besteht. Die Klasse ItemData hat ein Array namens Values. Die Liste ist an die Ansicht gebunden. Wir müssen entscheiden, was Datatemplate in Abhängigkeit davon, zu verwenden, was Eigenschaft ItemData wir Zugriff auf:

  1. One für den Namen
  2. Eines oder mehr für die Optionen arrray.

Aktuell zeigen wir die Liste in einer ListView an. Beim Generieren der ListView haben die Spalten unterschiedliche DataTemplates an ihre CellTemplate s, eine pro Index, für insgesamt 8 DataTemplates.

+0

Verwenden Sie ein ItemsControl mit 'ItemsSource = {Binding Values}'? – Clemens

+0

Das habe ich gemeint. – Clemens

+0

@MKII können Sie den Code von einigen anderen DataTemplates geben, die Sie definiert haben, wie ich sehen möchte, wie komplex sie sind/sein könnten? –

Antwort

1

Meine Antwort konzentriert sich auf Ihre Wörter: Da es eine große Anzahl von Eingabetypen gibt, bedeutet dies eine lächerliche Menge an wiederholtem Code.

Wiederverwendung von Code:

Da Sie in Ihrem Item template Bedarf verschiedene Arten von Kontrollen für verschiedene DataTypes, definieren, so dass der Code nicht vollständig reduziert werden kann. Ich meine, wenn Sie TextBox für String Typ oder Checkbox für Bool Typ möchten, kann dieser Code offensichtlich nicht reduziert werden. Was Sie jedoch reduzieren können, ist Binding Syntax immer wieder für verschiedene template zu definieren, wie ich in Ihrem TextBoxTemplate Beispiel sehen kann. Sie können die Biniding einmal definieren und dann wieder und wieder mit n Nummer (8 in Ihrem Fall) von Steuerelementen wiederverwendet. Unten ist, wie Sie es tun:

public class BindingResourceExtension : StaticResourceExtension 
{ 
    public BindingResourceExtension() : base() { } 

    public BindingResourceExtension(object resourceKey) : base(resourceKey) { } 

    public override object ProvideValue(IServiceProvider serviceProvider) 
    { 
     var binding = base.ProvideValue(serviceProvider) as BindingBase; 
     if (binding != null) 
      return binding.ProvideValue(serviceProvider); 
     else 
      return null; //or throw an exception 
    } 
} 

XAML

<Window.Resources> 
    <ResourceDictionary> 
     <Binding x:Key="MyBinding" Path="MyProperty" Mode="TwoWay" /> 
    </ResourceDictionary> 
</Window.Resources> 

(...) 

<TextBox Text="{ns:BindingResource MyBinding}" /> 
<CheckBox IsChecked="{ns:BindingResource MyBinding}" /> 

So können einige Wiederverwendung von Code erreicht (mit großen und komplexen bindings Imaging über Code) werden. Nachdem du deine Frage gepostet hast, war ich auf der Suche nach so etwas, also habe ich einen anderen question for binding reuse gepostet und es hat geholfen. Auch als Bindings werden zentralisiert werden sie einfach zu aktualisieren sein.

ItemTemplate:

Abgesehen von Ihrem Code-Wiederverwendung Problem können Sie Ihre Klasse digram verschachtelte ItemsControl als verwenden, indem Sie suchen kann ich sehen, und auch in einer anderen Antwort vorgeschlagen:

<ListBox ItemsSource="{Binding CollectionOfArrays}"> 
<ListBox.ItemTemplate> 
    <DataTemplate> 
     <ItemsControl ItemsSource="{Binding Array}" /> 
    </DataTemplate> 
</ListBox.ItemTemplate> 

Jetzt für innere ItemsControl müssen Sie tatsächlich die Templates definieren, aber ich denke Sie sind schon klar in diesem Teil.