2009-11-16 5 views
1

Je veux créer un datatemplate (en code, mais ce n'est pas le point) qui me permet de cliquer sur un élément et de définir sa valeur booléenne. Ce que j'ai réussi à créer était une combinaison de CheckBox et TextBlock, qui est colorée en fonction de la valeur de bool. Jusqu'ici tout va bien ... Mais comment dire à WPF: Si quelqu'un clique sur le TextBlock, changez la valeur de booléen. (supprimant la nécessité de la case à cocher laide)Utilisation d'un DataTemplate pour attacher OnClick au changement booléen

code à ce jour et travail:

var dT = new DataTemplate(typeof(DirectoryWrapper)); 
var stackPanel = new FrameworkElementFactory(typeof(StackPanel)); 

var style = new Style(typeof(TextBlock)); 
var t = new DataTrigger() {Binding = new Binding(DirectoryWrapper.PropString(x => x.IsSelected)), Value = true}; 
t.Setters.Add(new Setter() { Property = TextBox.ForegroundProperty, Value = new SolidColorBrush(Colors.Green) }); 
style.Triggers.Add(t); 


var box = new FrameworkElementFactory(typeof(CheckBox)); 
box.SetBinding(CheckBox.IsCheckedProperty, new Binding(DirectoryWrapper.PropString(x => x.IsSelected))); 
stackPanel.AppendChild(box); 

var entry = new FrameworkElementFactory(typeof(TextBlock)); 
entry.SetBinding(TextBlock.TextProperty, new Binding(DirectoryWrapper.PropString(x => x.Path))); 
entry.SetValue(TextBox.StyleProperty, style); 
stackPanel.AppendChild(entry); 

dT.VisualTree = stackPanel; 
return dT; 

Répondre

2

Ceci est trivial dans WPF: modèle Juste votre CheckBox pour ressembler à un TextBlock:

<CheckBox> 
    <CheckBox.Template> 
    <ControlTemplate> 
     <TextBlock Binding="{Binding WhateverYouWant}" ... /> 
    </ControlTemplate> 
    </CheckBox.Template> 
</CheckBox> 

Cela pourrait être étendu en ajoutant un Border autour du TextBlock ou toute autre chose vous aimez donner plus de pizzaz.

La raison pour laquelle vous souhaitez utiliser CheckBox au lieu de ToggleButton est que CheckBox a suport supplémentaire du clavier, ainsi que le soutien de accessibilty à la carte dans le paradigme de la case à cocher sur le périphérique accessibilty. ToggleButton ne vous donne pas ces fonctionnalités.

+0

Ce sont des moments où j'aime vraiment WPF. Travaillé comme un charme. Postet code pour votre solution ci-dessous dans un post séparé (pour les autres qui pourraient avoir besoin d'échantillons de code au lieu de XAML) –

+0

+1 pour solution de travail! Je cherchais une solution de contournement, mais cela fonctionne comme un charme! –

0

Cant vous utilisez un bouton à bascule et créer ne importe quel style/modèle de contrôle dont vous avez besoin pour obtenir votre look désiré. Un ToggleButton définira sa propriété IsChecked sur true ou false en fonction de votre clic. Donc, lier votre propriété de données à ToggleButton.IsSelected

0

Ok, juste pour convience, le code de travail pour Ray Burns, Solution:

(Pour les débutants: La fonction PropString est juste un emballage pour enlever les chaînes magiques, chaîne d'utilisation du nom de la propriété que vous lierez ici ..

var dT = new DataTemplate(typeof (DirectoryWrapper)); 

// Create style to set text red if checked 
var style = new Style(typeof (TextBlock)); 
var t = new DataTrigger() {Binding = new Binding(PropString(x => x.IsSelected)), Value = true}; 
t.Setters.Add(new Setter() {Property = Control.ForegroundProperty, Value = new SolidColorBrush(Colors.Red)}); 
style.Triggers.Add(t); 

// Create text box 
var entry = new FrameworkElementFactory(typeof(TextBlock)); 
entry.SetBinding(TextBlock.TextProperty, new Binding(PropString(x => x.Path))); 
entry.SetValue(FrameworkElement.StyleProperty, style); 

// Put into template 
var boxTemplate= new ControlTemplate(typeof(CheckBox)) {VisualTree = entry}; 

// Create box and set template 
var box = new FrameworkElementFactory(typeof (CheckBox)); 
box.SetBinding(ToggleButton.IsCheckedProperty, new Binding(PropString(x => x.IsSelected))); 
box.SetValue(Control.TemplateProperty, boxTemplate); 

dT.VisualTree = box; 
return dT; 
+0

Ça a l'air très bien. Pour votre information, vous serez surpris d'apprendre que dans ce cas, la création de l'objet dans le code est moins efficace que XAML. Pendant la compilation, votre XAML est converti en un format très efficace appelé "BAML". Ce format est en fait plus efficace que FrameworkElementFactory pour l'instanciation de modèles. Il économise également beaucoup de RAM à cause de certaines optimisations internes basées sur BAML dont FrameworkElementFactory ne peut tirer parti. Mais pour des raisons pratiques, cette différence de performance n'est pas très importante, de sorte que le choix du code par rapport à XAML devrait être basé sur d'autres facteurs. –

Questions connexes