Hello everybody I am trying to change the template of a column in my dataGrid but I cannot find the way to do it in XAML. I am trying to do it by this way
<DataTemplate>
<DataTemplate.Triggers>
<Trigger Property="{Binding ElementName=isComboBox, Path=IsChecked}"
Value="True">
<Setter Property="VisualTree">
<Setter.Value>
<ComboBox ItemsSource="{Binding elementos}"/>
</Setter.Value>
</Setter>
</Trigger>
</DataTemplate.Triggers>
</DataTemplate>
but an error show me that The property VisualTree cannot be set as a property element on template. Only Triggers and Storyboards are allowed as property elements
does any body know a different way to change template in a DataGridCell according another control ?
You don't change the template within the template, that's not how it works.
There are a number of ways to do this. Depends on how your application is configured. The most common method is
- A ContentControl or ItemsControl is bound to a property/collection
- The collection contains one or more instances of different types
- You define DataTemplates within the Resources of your application which have a DataType that matches your instance types
For example, you have a few Models in your application
public sealed class Foo
{
public string Text {get;set;}
}
public sealed class Bar
{
public bool Checked {get;set;}
}
Your application exposes a property that contains one or more of these instances
public partial class MainWindow : Window
{
//INotifyPropertyChanged/DependencyObject stuff left out!
public object FooOrBar {get;set;}
//snip
}
In your XAML, you have a UIElement type that extends ItemsControl or ContentControl or similar that can bind to the property.
<Window
x:Name="root"
xmlns:t="clr-namespace:MyApplicationWhereFooAndBarLive"
SkipAllThatXmlnsDefinitionNonsenseForSpaceSavingsInThisExample="true"/>
<!-- see Resources below -->
<ConentControl Content="{Binding FooOrBar, ElementName=root}" />
</Window>
Lastly, you define DataTemplates for each of your types within the Resources of your application
<Window.Resources>
<DataTemplate DataType="{x:Type t:Foo}">
<TextBox Text="{Binding Text}" />
</DataTemplate >
<DataTemplate DataType="{x:Type t:Bar}">
<CheckBox Checked="{Binding Checked}" />
</DataTemplate >
</Window.Resources>
The process of DataTemplate selection goes like this:
- Someone somewhere sets (we'll say in this example)
FooOrBar = new Foo();
- The ContentControl's Content binding updates (via INPC or DependencyProperty)
- The ContentControl looks for its DataTemplateSelector, finds none configured and uses the default implementation.
- The default DataTemplateSelector gets the type of the object bound to the Content property.
- The DataTemplateSelector (essentially) looks up the logical tree for a Resource that is a DataTemplate and that has a key of a type that matches the instance type identified in step 4.
- The DataTemplate is found, and is passed to the ConentControl
- The ContentControl Loads the visual tree within via the
LoadContent()
method.
- The ContentControl sets the DataContext of the root of this visual tree to the value within the Content property (in our case, the new instance of
Foo
)
- This visual tree is (IIRC) added as a child of the ConentControl and is now visible within the UI.
Roughly the same thing goes for an ItemsControl, except an intermediary is added (i.e., ListBox uses the ListBoxItem as an intermediary, and LBI is a ContentControl).