Programatically Update XAML Data Template in Windows 8 App - c#

I have a data template like so:
<DataTemplate x:Key="itemTmpl">
<Grid Margin="6">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Border Height="90" Width="90" Background="#eee" />
<StackPanel Grid.Column="1" VerticalAlignment="Top" Margin="10,0,0,0">
<TextBlock Text="{Binding Id}" Style="{StaticResource TitleTextBlockStyle}" TextWrapping="NoWrap"/>
</StackPanel>
</Grid>
</DataTemplate>
I am setting a List View Item Source in the code behind like so:
lv.ItemTemplate = (DataTemplate)this.Resources["itemTmpl"];
How can I programatically change the Border Background before the template gets rendered to my UI?

You can do a few things:
Parse the Visual Tree (using a VisualTreeHelper or extension method such as from WinRTXamlToolkit), find the border (likely by its x:Name) and set the Background.
Bind the Background to a value in your Item
Bind the Background to a value in your VM
For any of the two Bindings, you can use a Converter to convert from a non-brush value to the proper brush value (such as if you wanted it to change colors based on if it were Checked, a bool, or not).
For the second binding, make sure that you set the Source to your VM, as the DataContext will be, by default, your Item. Also, make sure that your Item inherits from INotifyPropertyChanged so that your Bindings will get updated based on the changes in data properly.

Related

How to change listview datatemplate in c# dynamically

I have a custom made item template for my listview with which values getting bound in .xaml itself.
I want to change one of the image dynamically in c# side.
I know in c# I can change in ContainerContentChanging but I am not able to access the custom templates image in c# please guide me out of this problem.
Here is my listview
<ListView ItemsSource="{Binding testList}" IsItemClickEnabled="True" ContainerContentChanging="ListView_ContainerContentChanging">
<ListView.ItemTemplate>
<DataTemplate>
<Grid HorizontalAlignment="Stretch">
<Grid.RowDefinitions>
<RowDefinition Height="1*" />
<RowDefinition Height="2" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0.80*"></ColumnDefinition>
<ColumnDefinition Width="0.20*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<StackPanel Margin="0,8,0,8" Grid.Row="0" Grid.Column="0" VerticalAlignment="Center">
<StackPanel Orientation="Horizontal">
<TextBlock FontSize="20" Margin="0,8,0,4" Text="{Binding textVal1}" />
<Image Name="imgStatus" Source="ms-appx:///Assets/Icons/ic_test.png" Height="36" />
</StackPanel>
<TextBlock FontSize="18" Margin="0,0,0,4" Text="{Binding textVal2}" />
<TextBlock FontSize="21" Margin="0,0,0,0" Text="{Binding textVal3}" TextWrapping="WrapWholeWords" MaxLines="2" />
</StackPanel>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
I thought lets have the data template in a separate c# file ... but I am not able to link up the c# file inside the grid.
Any help to access the image from the data template is appreciated.
If you define the templates as a static resource, or elsewhere where they can be referenced in XAML, you can use a custom converter with appropriate bindings to handle the change in template.
However, I believe changing the ListView.ItemTemplate will affect all items in the collection. In order to change the template of individual items, you will have to add a wrapper object and modify that object's content (which you can do in a similar manner).
I understand you wished to change the template in C#, but I believe XAML's declarative style should be sufficient.

WPF - Commands and referencing objects

So I have got C# 5.0 All-In-One for Dummies, but it doesn't really show a good example for what I want to achieve. Here is my XAML:
<StackPanel Grid.Column="1">
<Grid>
<Image Source="Images/039.JPG" x:Name="example_image"/>
<Image Source="Images/example.png" HorizontalAlignment="Right" VerticalAlignment="Bottom" Panel.ZIndex="999" x:Name="example_logo"/>
</Grid>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="8*"/>
<ColumnDefinition Width="1*"/>
</Grid.ColumnDefinitions>
<Slider Grid.Column="0" Margin="10" Maximum="100" SmallChange="1" ToolTip="Watermark size in percent (%)" Value="{Binding Path=SliderValue, Source={x:Static Application.Current}}"/>
<TextBlock Grid.Column="1" Text="{Binding Path=SliderValue, Source={x:Static Application.Current}}" HorizontalAlignment="Center" VerticalAlignment="Center" />
</Grid>
</StackPanel>
So I have got 2 images, one image 1 (the watermark) on top of the other image 2. And I have got a slider, which I have Binded to a value in my App.xaml.cs.
What I need to do is code a custom command, which will fire when the slider is moved, I need to add some parameters to this command which will be the 2 images names, so I can manipulate these controls using the command.
I can't seem to workout how I would do this, I have made a separate file for my commands called Commands.cs.
Why do I want to send the 2 images names as parameters, well so the command is reusable, if I want to use a different image control.
How would I go about doing this?
There isn't a Command property on the Slider although it's possible to add one (see https://gist.github.com/anonymous/4326429)
A simple option would be to handle the ValueChanged event on the Slider or perhaps if the SliderValue property on App.xaml.cs is a then you could fire your reusable "command" code from its setter.
Side note, you may want to look into the MVVM pattern rather than putting all your code in the code behind.

How to change telerik WPF RadGridView column filtering view template

We are using telerik controls in our project. I want to change telerik Radgrid view's (For WPF) filtering view.
As of now it looks like this as shown below:
And I want to change the text being show to actual color, so that it looks more realistic for the user to filter. Something like this:
How to get hold of the template of filtering view and inject the color rectangle there.
How to get hold of the template of filtering view and inject the color rectangle there.
The ControlTemplate can be found in Telerik.Windows.Controls.GridView.xaml:
<ControlTemplate x:Key="FilteringControlTemplate" TargetType="grid:FilteringControl">
...
I customized the ItemTemplate (for the Office2013 theme) to achieve the following, which should give you an indication of what needs to be done. You could also have a look at the CustomFilterControl example.
<ListBox.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="20" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<CheckBox
Content=""
FontSize="13"
Grid.Column="0"
IsChecked="{Binding IsActive, Mode=TwoWay}"
VerticalAlignment="Center"/>
<Rectangle
Fill="{Binding ConvertedValue, Converter={StaticResource DistinctValueConverter}}"
Grid.Column="1"
Height="16"
Width="30" />
</Grid>
</DataTemplate>

How to bind controls to different source from a datatemplate

I have a simple design with several hubsections into which I want to display a ListBox inside a Grid. The ListBox itself will contain two elements : a TextBlock and a TextBox.
The TextBlock in each HubSection will display the same property, so the data binding is quite easy. However, the TextBox should display a different property in each separate HubSection. I am lost and do not even have a clue on how I should proceed.
Here is my XAML code :
<Page.Resources>
<ResourceDictionary>
<DataTemplate x:Key="BaseGridTemplate">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto"></ColumnDefinition>
<ColumnDefinition Width="12"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<TextBlock
Text="{Binding PlayerName}"
FontSize="28"/>
<TextBox Text="{Binding OtherProperty, Mode=TwoWay}"
Background="Lavender" FontSize="28"
Grid.Column="2">
</TextBox>
</Grid>
</DataTemplate>
</ResourceDictionary>
</Page.Resources>
Then in my HubSections, I want to use the above template to display data, like such:
<HubSection Width="350" x:Uid="Test" Header="Test">
<DataTemplate>
<ListBox x:Name="TestListBox" Grid.Column="1"
ItemsSource="{Binding}"
ItemTemplate="{StaticResource BaseGridTemplate}"
>
</ListBox>
</DataTemplate>
</HubSection>
In my UI, both properties (PlayerName and OtherProperty) are displayed correctly. But what I would like to do is to bind to a different property for the TextBox (i.e. different from OtherProperty).
I really have no clue on how I should proceed, or if it even is possible.
I thought I could to something like defining my TextBox in the Resources section like such :
<TextBox Text="{Binding, Mode=TwoWay}">
And then Hope I could add something in the HubSection part ?
Assuming you have a way of knowing when you have to use your different properties I think the best way for you to do this is to use a template selector and have different kind of templates based on what you want to display.
Another alternative would be to use a value converter for TextBox and use the binding you suggested:
<TextBox Text="{Binding, Mode=TwoWay, Converter={StaticResource YourConverter}">
These are just some ideas to get you started, another important thing to know is if are you trying to use a different property on the same object?

Get element inside a DataTemplate

I have a following XAML and I need to change visibility of imageRemoveButton at runtime from the code behind file. How do I access that button?
<ItemsControl x:Name="ImagesItemsControl">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Border BorderBrush="#ffdddddd"
BorderThickness="0,0,0,1">
<Grid Margin="0,2">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="15" />
<ColumnDefinition />
<ColumnDefinition Width="20" />
</Grid.ColumnDefinitions>
<Grid Grid.Column="1"
VerticalAlignment="Center">
<TextBlock Text="{Binding Name}"
TextWrapping="Wrap" />
</Grid>
<Button Grid.Column="3"
Width="20"
Height="20"
Content="X"
Template="{StaticResource ButtonAddTab}"
Style="{StaticResource ButtonWizard}"
Tag="{Binding}"
x:Name="imageRemoveButton"
Click="ImageRemoveButton_Click" />
</Grid>
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
Use the loaded event on the button to save a reference to the button in the cs file. Use this reference when needed to change the visibility.
You cannot reference-by-name elements in a template. There is no matching code-behind/designer property generated by templates.
You want to bind the visibility of a control in the template to a property of your data items. That means you will need to add a property to your data items. Can you provide more details of your data items? If the property is a bool value, use a VisibilityConvertor (dime a dozen on this site).
Think of templates as wanting to always pull settings from the bindings, rather than have settings stuffed into them from the outside.
Try using Source binding to a class that will manage the button's visibility state. Adding a property to all your data items would be painfull but could be required if the button's visibility needs to be set based on a property of your data item. As per standard MVVM patterns you can then control the button's visibility from C#. If you need a specific instance of the button you can add a Loaded event handler to it and cache it accordingly.

Categories