La creazione di un editor di WPF per il file XML basato su schema

Ecco lo scenario. Utilizziamo un grande file di configurazione XML per uno dei nostri prodotti server. Questo file è abbastanza ben disposti e viene convalidato un file XSD.

È tempo ora, però, per costruire una interfaccia di configurazione per il mantenimento di questo file e vorrei immersione in WPF per farlo. Ho potuto disporre di una forma separata per ogni sezione config, refactoring e la ridistribuzione ogni volta che si aggiunge un’opzione per la config, ma sto sperando che ci sia un metodo più intelligente per farlo.

Dato che ho già fortemente tipizzato xml/xsd combinazione sto sperando che ci sia un metodo elegante per la costruzione di una interfaccia utente per modificare questo abbastanza facilmente. So che potrei scrivere un xml->xaml trasformazione, ma è stato sperando che ci sia qualcosa là fuori per fare il sollevamento di carichi pesanti per me già?

Grazie in anticipo..

 

4 Replies
  1. 12

    Come mi piacerebbe fare questo:

    Mi piacerebbe iniziare con la costruzione di un semplice modello di classe che si avvolge attorno ad un XmlElement e lo espone come opzione di configurazione. Questa classe può essere estremamente semplice, ad esempio:

    public class OptionView
    {
       private XmlElement XmlElement;
       public OptionView(XmlElement xmlElement)
       {
          XmlElement = xmlElement;
       }
       public string Name { get { return XmlElement.Name; } }
       public string Value 
       { 
          get { return XmlElement.InnerText; } 
          set { XmlElement.InnerText = value; }
       }
    }

    Ora posso compilare una raccolta di ElementView di oggetti da un XmlDocument, aggiungere che la raccolta della finestra ResourceDictionary e formattare gli oggetti con un semplice DataTemplate, ad esempio:

    <DataTemplate x:Key="OptionViewTemplate" DataType={x:Type local:OptionView}>
       <Grid>
           <Grid.ColumnDefinitions>
              <ColumnDefinition SharedSizeGroup="Name"/>
              <ColumnDefinition SharedSizeGroup="Value"/>
           </Grid.ColumnDefinitions>
           <Label Content="{Binding Name}" Grid.Column="0"/>
           <TextBox Text="{Binding Value}" Grid.Column="1"/>
       </Grid>
    </DataTemplate>
    ...
    <ItemsControl Grid.IsSharedSizeScope="True"
        ItemsSource="{DynamicResource OptionCollection}"/>

    (Nota: in Seguito, si può ottenere qualcosa in più, e definire sottoclassi di OptionView sulla base, per esempio, il tipo di dati del sottostante XmlElement. Quindi è possibile definire DataTemplates per ogni sottoclasse, e fintanto che presenta la voce in due colonne della griglia utilizzando che SharedSizeGroup, la seconda colonna può contenere un selettore data o pulsanti di opzione, o tutto ciò che è appropriato per la sottoclasse, e tutti ordinatamente disposti in fase di runtime.)

    Una volta ho avuto che di lavoro, che non richiede molto tempo, mi piacerebbe iniziare estendendo la OptionView classe. Per esempio, se il tuo schema è la memorizzazione di un leggibile l’etichetta di un elemento in un xs:annotation elemento (e se non lo è, perché no?), Mi piacerebbe fare il Name proprietà dell’estratto di fuori del XmlElement‘s SchemaInfo proprietà, invece di esporre il sottostante nome di un elemento.

    Ovviamente vorrei aggiungere la convalida, quindi mi piacerebbe aggiungere un metodo di convalida che ha esaminato il XmlElement‘s SchemaInfo proprietà e interpretato. (Assumendo che gli elementi che si sta convalida sono semplici di contenuto, che non dovrebbe essere difficile.) Ci sono milioni di tutorial su come implementare la convalida in applicazioni WPF, quindi non voglio andare troppo nel dettaglio qui.

    Se ci sono tonnellate di opzioni di configurazione e si dispone di alcune modo intelligente di loro raggruppamento in categorie, mi piacerebbe costruire una classe di livello superiore che ha esposto (almeno) due proprietà – una stringa CategoryName proprietà e un OptionsViews collezione – la popolano dal documento XML, e aggiungere alla finestra ResourceDictionary. All’interno della finestra, mi piacerebbe associare a una TabControl, ad esempio:

    <TabControl ItemsSource="{DynamicResource OptionCategories}">
       <TabControl.ItemContainerStyle>
          <Style TargetType="{x:Type CategoryView}">
             <Setter Property="Header" Value="{Binding Path=CategoryName}"/>
             <Setter Property="Content" Value="{Binding Path=OptionsViews}"/>
             <Setter Property="ContentTemplate" Value="{StaticResource OptionViewTemplate}"/>
          </Style>
       </TabControl.ItemContainerStyle>
    </TabControl>

    O per qualche elemento di controllo, il cui elemento contenitore modello consente di creare un Expander. O qualcosa del genere. (Tutto il codice non testato, garantito! La maggior parte di esso è stato copiato di progetti, però.)

    Se non hai fatto niente con WPF prima, questo è un buon progetto per iniziare. Ti esporre i fondamenti di associazione di dati e di elementi di controlli e verifiche, e il risultato finale sarà qualcosa di utile e, probabilmente, sembra piuttosto buono.

    E si noterà che, mentre il markup coinvolti nella creazione dei modelli è abbastanza dettagliato, ci sono solo due modelli. Il solo codice dell’applicazione (finora) è il codice che espone il XmlElements UI.

    • Alcuni utili brainfood ci Robert, grazie.
  2. 4

    Ecco a voi, abbiamo creato uno per il vostro requisito. questo strumento completamente creato da mantenere WPF in mente.

    http://wpfxmleditor.codeplex.com/

    • Pensi di fare una versione per il tuo editor? Attualmente è solo fonte e non c’è alcuna indicazione di stato del codice, vale a dire, è quasi completo? alfa, beta, stabile?)
    • mi dispiace per il ritardo della risposta, non ho alcun piano per il rilascio, è possibile scaricare e costruire.
  3. 0

    Per presentare xml semplice file di configurazione (se editor personalizzati per i valori non sono obbligatori) si può associare direttamente XElement di una vista utilizzando HierarchicalDataTemplate.

    xaml:

    <TreeView Grid.IsSharedSizeScope="True" 
              ItemsSource="{Binding Xml.Elements}">
        <TreeView.ItemTemplate>
            <HierarchicalDataTemplate ItemsSource="{Binding Elements}">
                <Grid>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition SharedSizeGroup="Name"/>
                        <ColumnDefinition SharedSizeGroup="Value"/>
                    </Grid.ColumnDefinitions>
                    <Label Content="{Binding Name}" />
                    <!--Show TextBox only for leaf elements-->
                    <TextBox Grid.Column="1"
                             Text="{Binding Value}" 
                             Visibility="{Binding HasElements,
                                Converter={StaticResource reverseBoolToVisibilityConverter}}"/>
                </Grid>
            </HierarchicalDataTemplate>
        </TreeView.ItemTemplate>
    </TreeView>

    modello di visualizzazione:

    class ConfigViewModel:INotifyPropertyChanged
    {
        public XElement Xml { get; private set;}
    
        //example of persistence infrastructure
        public event PropertyChangedEventHandler PropertyChanged = delegate { };
        public void Load(string fileName)
        {
            Xml = XElement.Load(fileName);
            PropertyChanged(this, new PropertyChangedEventArgs("Xml"));
        }
        public void Save(string fileName)
        {
            Xml.Save(fileName);
        }
    }

    Ci sono alcuni buoni esempi per invertita bool visibilità converter.

Lascia un commento