2009-11-26 9 views
11

Ho avuto molti controlli utente in questo modo:Qual è il modo migliore per riutilizzare i blocchi di XAML?

PageManageCustomers.xaml.cs:

public partial class PageManageCustomers : BasePage 
{ 
... 
} 

che ereditano da:

PageBase.cs:

public class BasePage : UserControl, INotifyPropertyChanged 
{ 
... 
} 

dal PageBase.c s non ha nessun file XAML associato, devo mettere il XAML a cui fa riferimento in ogni dei controlli utente che lo ereditano, ad es. il seguente blocco si ripete in ogni file XAML di ogni controllo che eredita PageBase:

<DataTemplate x:Key="manageAreaCellTemplate"> 
    <StackPanel Orientation="Horizontal"> 
     <TextBlock Style="{DynamicResource ManageLinkStyle}" 
    Tag="{Binding Id}" Text="Delete" MouseDown="System_Delete_Click"/> 
     <TextBlock Text=" "/> 
     <TextBlock Style="{DynamicResource ManageLinkStyle}" 
      Tag="{Binding Id}" Text="Edit" MouseDown="System_Edit_Click"/> 
    </StackPanel> 
</DataTemplate> 

Sto cercando di mettere questo blocco in un file di risorse ma non riesco a ottenere la giusta sintassi, si dice :

'ResourceDictionary' elemento radice richiede ascia: Classe attributo gestori di eventi di supporto nel file XAML . Rimuovere il gestore eventi per l'evento MouseDown oppure aggiungere un attributo x: Class all'elemento root.

O forse ho potuto leggere questi blocchi con XamlReader `in qualche modo?

Come posso inserire questo blocco ripetuto di codice in un posto in modo che non venga ripetuto in ogni file XAML che eredita BagePage?

Ecco un esempio riproducibile di questo problema:

Window1.xaml:

<Window x:Class="TestXamlPage8283.Window1" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Title="Window1" Height="300" Width="300"> 
    <StackPanel x:Name="MainContent"/> 
</Window> 

Window1.xaml.cs:

using System.Windows; 

namespace TestXamlPage8283 
{ 
    public partial class Window1 : Window 
    { 
     public Window1() 
     { 
      InitializeComponent(); 

      Page1 page1 = new Page1(); 
      MainContent.Children.Add(page1); 

      Page2 page2 = new Page2(); 
      MainContent.Children.Add(page2); 
     } 
    } 
} 

Page1.xaml :

<local:BasePage x:Class="TestXamlPage8283.Page1" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:local="clr-namespace:TestXamlPage8283" 
    Height="40" Width="300"> 
    <StackPanel> 
     <TextBlock Text="{Binding PageTitle}" 
        FontSize="14" 
        FontWeight="Bold"/> 
     <TextBlock Text="This is XAML that is specific to page one." /> 
    </StackPanel> 
</local:BasePage> 

Page1.xaml.cs:

namespace TestXamlPage8283 
{ 
    public partial class Page1 : BasePage 
    { 
     public Page1() 
     { 
      InitializeComponent(); 
      PageTitle = "Page One"; 
     } 
    } 
} 

Page2.xaml:

<local:BasePage x:Class="TestXamlPage8283.Page2" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:local="clr-namespace:TestXamlPage8283" 
    Height="40" Width="300"> 
    <StackPanel> 
     <TextBlock Text="{Binding PageTitle}" 
        FontSize="14" 
        FontWeight="Bold"/> 
     <TextBlock Text="This is XAML that is specific to page two." /> 
    </StackPanel> 
</local:BasePage> 

Page2.xaml.cs:

namespace TestXamlPage8283 
{ 
    public partial class Page2 : BasePage 
    { 
     public Page2() 
     { 
      InitializeComponent(); 
      PageTitle = "Page Two"; 
     } 
    } 
} 

BasePage.cs:

using System.Windows.Controls; 
using System.ComponentModel; 

namespace TestXamlPage8283 
{ 
    public class BasePage : UserControl, INotifyPropertyChanged 
    { 
     #region ViewModelProperty: PageTitle 
     private string _pageTitle; 
     public string PageTitle 
     { 
      get 
      { 
       return _pageTitle; 
      } 

      set 
      { 
       _pageTitle = value; 
       OnPropertyChanged("PageTitle"); 
      } 
     } 
     #endregion 

     public BasePage() 
     { 
      DataContext = this; 
     } 

     #region INotifiedProperty Block 
     public event PropertyChangedEventHandler PropertyChanged; 

     protected void OnPropertyChanged(string propertyName) 
     { 
      PropertyChangedEventHandler handler = PropertyChanged; 

      if (handler != null) 
      { 
       handler(this, new PropertyChangedEventArgs(propertyName)); 
      } 
     } 
     #endregion 
    } 
} 

Come faccio a prendere questa blocco

<TextBlock Text="{Binding PageTitle}" 
      FontSize="14" 
      FontWeight="Bold"/> 

fuori di Page1.xa ml e Page2.xaml e metterlo in uno posto così posso riferire ad esso da Page1.xaml e Page2.xaml? (in modo che quando voglio cambiare FontSize = 14 al FontSize = 16, ho solo bisogno di cambiare in un unico luogo)

+0

Sembra che quello che stai chiedendo sia qualcosa di simile alle pagine master di Asp.net. Non so se è possibile. Per il tuo ultimo esempio di TextBlock (modificando il FontSize del blocco di testo PageTitle), non è questo il significato degli stili? –

risposta

5

Utilizzare i dizionari risorse - aggiungere un file MyDictionary.xaml al progetto, impostando la sua azione di costruzione a "Pagina ":

<ResourceDictionary 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> 
    <DataTemplate x:Key="manageAreaCellTemplate"> 
     <StackPanel Orientation="Horizontal"> 
      <TextBlock Style="{DynamicResource ManageLinkStyle}" 
       Tag="{Binding Id}" Text="Delete" MouseDown="System_Delete_Click"/> 
      <TextBlock Text=" "/> 
      <TextBlock Style="{DynamicResource ManageLinkStyle}" 
       Tag="{Binding Id}" Text="Edit" MouseDown="System_Edit_Click"/> 
     </StackPanel> 
    </DataTemplate> 
</ResourceDictionary> 

Poi in altri file XAML che si riferiscono ad essa con:

<ResourceDictionary> 
    <ResourceDictionary.MergedDictionaries> 
     <ResourceDictionary Source="MyDictionary.xaml"/> 
    </ResourceDictionary.MergedDictionaries> 
    ... some other local resources ... 
</ResourceDictionary> 

e si riferiscono alla risorsa come Template={StaticResource manageAreaCellTemplate}.

+0

Quando faccio questo mi dice: "L'elemento root 'ResourceDictionary' richiede ax: attributo di classe per supportare i gestori di eventi nel file XAML, oppure rimuovere il gestore di eventi per l'evento MouseDown o aggiungere ax: attributo di classe all'elemento root. " quando aggiungo l'attributo x: Class, ottengo errori come questo: "Modificatore parziale mancante sulla dichiarazione di tipo" TestApp.Pages.BasePageManageItems ", esiste un'altra dichiarazione parziale di questo tipo" –

+1

Proprio così hai eventi 'MouseDown' che non possono essere vincolato al momento della compilazione in quanto il dizionario non ha codice dietro. È necessario aggiungere gestori di eventi in fase di esecuzione o utilizzare i comandi: http://msdn.microsoft.com/en-us/library/ms752308.aspx. – Mart

Problemi correlati