2011-01-18 15 views
3

J'ai été perplexe avec essayer de convertir le code suivant en C# pur. Ce code XAML provient du blog de Cavanaghs sur comment faire des coins arrondis sur n'importe quoi. Le code fonctionne mais j'ai besoin de le convertir en C# car j'en ai besoin pour être dynamique dans certains cas. Si vous pouviez aider cela serait génial.Conversion ControlTemplate XAML en C#

<Setter Property="Template"> 
<Setter.Value> 
    <ControlTemplate TargetType='{x:Type ListViewItem}'> 
     <Grid> 
      <Border CornerRadius="15" Name="mask" Background="White"/> 
      <StackPanel Background="Beige"> 
       <StackPanel.OpacityMask> 
        <VisualBrush Visual="{Binding ElementName=mask}"/> 
       </StackPanel.OpacityMask> 
       <GridViewRowPresenter Content="{TemplateBinding Content}" Columns="{TemplateBinding GridView.ColumnCollection}"/> 
       <TextBlock Background="LightBlue" Text="{Binding News}" /> 
      </StackPanel> 
     </Grid> 
    </ControlTemplate> 
</Setter.Value> 

Jusqu'à présent, je donne les résultats suivants, mais je reçois des erreurs.

FrameworkElementFactory border = new FrameworkElementFactory(typeof(Border)); 
border.SetValue(Border.BackgroundProperty, Brushes.White); 
border.SetValue(Border.CornerRadiusProperty, new CornerRadius(8, 8, 8, 8)); 
border.SetValue(Border.NameProperty, "roundedMask"); 

Pour autant que je peux dire que je ne peux pas faire la VisualBrush comme FrameworkElementFactory (accidents), mais si je déclare comme un élément régulier VisualBrush je ne peux pas passer la frontière en tant visuelle depuis son FrameworkElementFactory un.

Simplement je me perds, toute aide serait appréciée. Merci pour toute aide

+1

Vous savez que vous pouvez fournir un nom à l'élément en question dans XAML puis le référencer dans le code derrière pour fournir la capacité dynamique que vous désirez. Vous n'avez pas besoin de construire l'ensemble de l'élément dans le code derrière. –

+0

Pour référence ultérieure, XAML est analysé en C# (ou VB dans un projet VB). Après la compilation, regardez dans le dossier .obj pour 'MyXamlFile.g.cs'. Il contient le code analysé. – Tergiver

+1

@Tergiver ce n'est pas précis (au moins plus) - XAML génère .BAML (dans WPF) et Codebehind C#/VB etc. Le code est pour assigner les références nommées aux variables de classe (codebehind est une classe partielle qui complète le BAML) –

Répondre

3

Vous ne voulez pas le savoir. Sérieusement, non, c'est un cauchemar.

Edit: Si je ne fais aucune erreur c'est la traduction de votre code ...

Setter setter = new Setter(); 
setter.Property = ListViewItem.TemplateProperty; 
ControlTemplate template = new ControlTemplate(typeof(ListViewItem)); 
var grid = new FrameworkElementFactory(typeof(Grid)); 
var border = new FrameworkElementFactory(typeof(Border)); 
border.SetValue(Border.BackgroundProperty, Brushes.White); 
border.SetValue(Border.NameProperty, "mask"); 
border.SetValue(Border.CornerRadiusProperty, new CornerRadius(15)); 
grid.AppendChild(border); 
var stackPanel = new FrameworkElementFactory(typeof(StackPanel)); 
stackPanel.SetValue(StackPanel.BackgroundProperty, Brushes.Beige); 
var visualBrush = new FrameworkElementFactory(typeof(VisualBrush)); 
visualBrush.SetBinding(VisualBrush.VisualProperty, new Binding() { ElementName = "mask" }); 
stackPanel.SetValue(StackPanel.OpacityMaskProperty, visualBrush); 
var gridViewRowPresenter = new FrameworkElementFactory(typeof(GridViewRowPresenter)); 
gridViewRowPresenter.SetValue(GridViewRowPresenter.ContentProperty, new TemplateBindingExtension(GridViewRowPresenter.ContentProperty)); 
gridViewRowPresenter.SetValue(GridViewRowPresenter.ColumnsProperty, new TemplateBindingExtension(GridView.ColumnCollectionProperty)); 
stackPanel.AppendChild(gridViewRowPresenter); 
var textBlock = new FrameworkElementFactory(typeof(TextBlock)); 
textBlock.SetValue(TextBlock.BackgroundProperty, Brushes.LightBlue); 
textBlock.SetBinding(TextBlock.TextProperty, new Binding("News")); 
stackPanel.AppendChild(textBlock); 
grid.AppendChild(stackPanel); 
template.VisualTree = grid; 
setter.Value = template; 

Edit: Il y a encore un bug gauche, le VisualBrush ne peut pas être créé comme cela, le reste semble fonctionner.

+0

Droit, c'est ce que je suis coincé. Il semble que vous deviez créer le visualbrush directement à savoir VisualBrush vbrush = new VisualBrush. Mais alors je ne peux pas passer la frontière directement car ce n'est pas un visuel mais un FrameworkElementFactory ... C'est la partie qui m'a dérouté ... merci pour l'aide cependant. – Nithos

+0

Coincé exactement au même endroit.Il ne semble pas y avoir de logique dans FrameworkFactory pour appliquer des usines enfants aux propriétés exposées. C'est peut-être ce dont il est question dans la clause de non-responsabilité concernant le cours qui est obsolète. Il existe divers exemples montrant le code XAML incorporé, mais cela pose aussi des problèmes. –

+0

probablement qu'ils utilisent un convertisseur de valeur en interne, vous pouvez essayer de trouver celui qu'il est et l'appeler –

6

Vous n'avez pas besoin de convertir cela en C# pour l'appliquer dynamiquement. Si vous ajoutez à vos ressources d'application, dans votre fichier App.xaml comme suit:

<Application.Resources> 
    <ControlTemplate TargetType='{x:Type ListViewItem}' x:Key="MyListViewItemTemplate"> 
     <Grid> 
      <Border CornerRadius="15" Name="mask" Background="White"/> 
      <StackPanel Background="Beige"> 
       <StackPanel.OpacityMask> 
        <VisualBrush Visual="{Binding ElementName=mask}"/> 
       </StackPanel.OpacityMask> 
       <GridViewRowPresenter Content="{TemplateBinding Content}" Columns="{TemplateBinding GridView.ColumnCollection}"/> 
       <TextBlock Background="LightBlue" Text="{Binding News}" /> 
      </StackPanel> 
     </Grid> 
    </ControlTemplate> 
</Application.Resources> 

Remarque x: attribut clé qui clés de cet ouvrage.

Vous pouvez ensuite le chercher partout dans votre code ...

ControlTemplate template = this.Findresource("MyListViewItemTemplate") as ControlTemplate 

Vous pouvez ensuite appliquer comme et quand vous en avez besoin!

+0

Oui c'est vrai je peux le faire, mais ma curiosité me fait et je veux vraiment savoir à quoi ressemblera le code C# pour cela. Je trouve simplement incroyable combien il est plus difficile de faire cela dans le code. Ce n'est tout simplement pas si évident que ça. Merci pour l'idée cependant. – Nithos

+0

il y avait un outil XamlIt de ce que j'ai lu qui devrait être en mesure de convertir un tel XAML en C#, mais ne peut plus le trouver en ligne –