I have a ListBox showing data about employees such as name, department photo, badge number, etc. Employees may have different types such as Manager, Staff, Volunteers. I have 3 separate data templates - one for each type. All of these templates show basically the same data but presented differently.
Depending on the user logged into the application pictures, Badge Number, etc, can or cannot be visible. So I have boolean properties for that - CanSeePhotos, CanSeeBadgeNumbers, etc. So if CanSeePhotos == false, all data templates should hide the photos.
My question is, how can I use these boolean properties inside my data templates to toggle the visibility of the appropriate items? Is there a way to pass parameters to Data Templates as I return them from my TemplateSelector?
Thanks!
edit: following Ray's idea I ended up doing this:
Visibility="{Binding Source={x:Static local:Global.CanSeePhoto}, Converter={StaticResource BooleanToVisibilityConverter}}"
You use the ItemTemplate to specify the visualization of the data objects. If your ItemsControl is bound to a collection object and you do not provide specific display instructions using a DataTemplate, the resulting UI of each item is a string representation of each object in the underlying collection.
A ControlTemplate will generally only contain TemplateBinding expressions, binding back to the properties on the control itself, while a DataTemplate will contain standard Binding expressions, binding to the properties of its DataContext (the business/domain object or view model).
DataTemplate is about the presentation of data and is one of the many features provided by the WPF styling and templating model. For an introduction of the WPF styling and templating model, such as how to use a Style to set properties on controls, see the Styling and Templating topic.
A template binding is a special type of data binding that allows you to reference the parent control, read its properties and apply their values. In some cases, you can use the values directly. In other situations you may need to apply value converters or additional formatting.
Actually there is a way to customize DataTemplates as they are returned from the TemplateSelector by wrapping them inside a FrameworkElementFactory, but it is much too complex for your needs.
For your case there are two solutions that are much easier: triggers and converters.
Triggers
You can use a trigger inside the DataTemplate. For example, give the TextBox or Panel where you display the badge number an x:Name, then create a DataTrigger on the CanSeeBadgeNumebers property. Add one setter to the DataTrigger and set the Visible property to Hidden or Collapsed, referencing it by name.
Basic idea:
<DataTemplate>
...
<DockPanel x:Name="BadgeNumberPanel">
<Label ... />
<TextBox ... />
</DockPanel>
...
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding CanSeeBadgeNumbers}" Value="true">
<Setter ElementName="BadgeNumberPanel" Property="Visibility" Value="Collapsed" />
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
Converters
You can create an IValueConverter in code that converts "bool" type to "Visibility" type (there are many examples out there you can cut and paste), then bind the visibilty of the TextBox to the CanSeeBadgeNumbers, using the converter.
<DockPanel Visibility="{Binding CanSeeBadgeNumbers, Converter="{x:Static local:BoolToVisibilityConverter.Instance}}">
<Label ... />
<TextBox ... />
</DockPanel>
How I Do It
I actually use a different technique for my own code: My data foundation includes a MarkupExtension I wrote that calls my core C# expression parser, so I can say something like
Visibility="{edf:Visibility CanSeeBadgeNumber || Owner.SecurityLevel.Count() > 3}"
Unfortunately my data foundation has not yet been released. When it is, I plan to make it free and open source, but that's a few months away yet.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With