Conditionally setting colour of a bound element in XAML based on another field of datasource - xaml

I have the following item template in a WP7 listbox. My bound type has a boolean property (Status) and I would like to conditionally set the colour of the site name based on this. How would I go about doing this please?
Thanks in advance!
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Margin="0,0,0,17" Width="432">
<TextBlock Text="{Binding SiteName}" TextWrapping="Wrap" />
<TextBlock Text="{Binding Url}" TextWrapping="Wrap" Margin="12,-6,12,0" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>

The easiest way to do this is with a converter. Either you can have the converter return a color, or you can have two TextBlocks each with the color you want, and use a Boolean to Visibility, and one that is a reverse visibility, converters to hide/show each of the controls.
One word of caution is that converters can be slow, so sometimes it's more performant to bind to a ViewModel and on that ViewModel provide the convetered values that you need.

Related

Apply Parallax effect into GridView

https://learn.microsoft.com/en-us/windows/uwp/design/motion/parallax
this is microsoft instruction to use the paralax they use the ListView to demo the effect
but my data is stored inside the Grid.View so can anyone show me how to implement into it ?
Microsoft said that we can use this with any element that contain the scrollviewer
ParallaxView works with GridView. The Source property of ParallaxView is for setting the element that either is or contains the ScrollViewer that controls the parallax operation. Here in your code snippet it bind the ForegroundElement to Source property but no such an element in. You need to name the GridView as ForegroundElement .
<GridView
x:Name="ForegroundElement"
IsItemClickEnabled="True"
ItemClick="Grid_Clicked"
ItemsSource="{x:Bind Icons}">
...
</GridView>
Besides this, the code snippet should work well. If you still cannot see the effects it may be caused by items count is not enough. ScrollViewer inside the GridView or ListView only be shown when the host control's layout space is being constrained smaller than the expanded content size, details please see ScrollViewer in a control template. You could try to add more items to check the effects.
Additionally, edit the question to add more details and avoid to put it as an answer.
<GridView Grid.Row="1" ItemsSource="{x:Bind Icons}" IsItemClickEnabled="True" ItemClick="Grid_Clicked">
<GridView.ItemTemplate>
<DataTemplate x:DataType="data:Icon">
<StackPanel>
<Image Width="200" Height="200" HorizontalAlignment="Center" Source="{x:Bind ImageCover}"/>
<TextBlock FontSize="16" VerticalAlignment="Center" Text="{x:Bind Title}"/>
<TextBlock FontSize="10" VerticalAlignment="Center" Text="{x:Bind Room}"/>
</StackPanel>
</DataTemplate>
</GridView.ItemTemplate>
</GridView>
this is where the data stored
and this is the parallax
<ParallaxView Source="{x:Bind ForegroundElement}" VerticalShift="50">
<!-- Background element -->
<Image x:Name="BackgroundImage" Source="Assets/turntable.png"
Stretch="UniformToFill"/>
</ParallaxView>

Bind properties to elements inside a Listview DataTemplate

I can't get databinding to work within a DataTemplate in Xamarin forms. I can get it to work with the ListView (i.e. binding the RowHeight), but once in the DataTemplate, setting things to a property of my ViewModel has no affect.
In the below example, if I set the ColumnDefinition.Width to a property, it is completely ignored, but setting it to a hard value works fine. I have put in a label to see what the property value is and it turns out blank when inside the Datatemplate, and I have re-checked that the property is correct because if I take the label out of the Listview, it displays the correct value.
Any ideas?
UPDATE:
My Class is "ParentPage" which has 2 properties: "Patients" and "Settings". Patients has an observable collection of "PatientList", How would I bind to the "Settings.Fontsize" shown below in the label. I have tried every combination I can think of:
<ListView x:Name="listView" ItemsSource="{Binding ParentPage.Patients.PatientsList}" RowHeight="{Binding ParentPage.Settings.RowHeight}" >
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Grid HorizontalOptions="FillAndExpand">
<Grid.RowDefinitions>
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Image Grid.Row="0" Grid.Column="0"
Source="{Binding Picture}" />
<Label TextColor="Red" Text="{Binding ParentPage.Settings.FontSize}"
HorizontalOptions="Center" />
</Grid>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
BindingContext, in other words "ItemsSource" for listview, is appliying to whole listview, include DataTemplate. So, if you wanna bind something, then it property should be in BindingContext, in your case it is Patients. So, Pasient class should include this property. But, there is a trick. Where you want bind something, that is not in listview binding context, then you should name your listview, like x:Name = "YourListView" and then in your datatemplate for your binding write this:
Property="{Binding Source={x:Reference Name = "YourListView"},
Path=BindingContext.YourNameOfPropertyInViewModel}"
With this, your property will use binding context of your listview element level, that is ViewModel in your case.

How to create DataTemplate for several Image objects? (XAML)

I try to display some Images that are stored in ObservableCollection to the xaml page. It's easy to bind xaml object with one image:
<Image Source="{Binding Image}" Stretch="UniformToFill"/>
But how to display a set of images, if I don't know how much images there are? I think that I need to create a DataTemplate, but how it works?
Sorry, I'm not familiar with XAML.
You need to choose one of several controls that commonly used to display multiple items, such as LongListSelector, ItemsControl, etc. Bind the control's ItemsSource to your ObservableCollection of image property. Then define ItemTemplate to tell the control how each item in the ItemsSource should be displayed. For example :
<ItemsControl ItemsSource="{Binding ImageCollection}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Image Source="{Binding}" Stretch="UniformToFill"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>

Changing width and height of Image inside a datatemplate

I have an image inside datatemplate. I want to change its height and width depending on certain conditions. How can I achieve that?
The XAML code I have:
<ListBox x:Name="options_stack" HorizontalAlignment="Left" Margin="198,569,0,33" Width="603" ScrollViewer.HorizontalScrollBarVisibility="Auto" ScrollViewer.VerticalScrollBarVisibility="Disabled" ScrollViewer.HorizontalScrollMode="Auto" Height="123" Style="{StaticResource ListBoxStyle}" ItemContainerStyle="{StaticResource ListBoxItemStyle}" >
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemTemplate>
<DataTemplate>
<Image x:Name="options_image" Source ="{Binding}" Stretch="Fill" Width="123" Height="123" MaxHeight="123" MaxWidth="123" Tapped="apply_accessory"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Option 1
Since you are binding source property I would create a data structure (to use as DataContext) to hold Source, Width and Height properties and then bind them:
<Image x:Name="options_image"
Source ="{Binding Source}"
Width="{Binding Width}" Height="{Binding Height}"
MaxWidth="{Binding Width}" MaxHeight="{Binding Height}"
Stretch="Fill" Tapped="apply_accessory"/>
Option 2
Another option is to create different DataTemplates and a DataTemplateSelector to apply when certain conditions are met.
DataTemplateSelector ref: http://msdn.microsoft.com/en-us/library/system.windows.controls.datatemplateselector.aspx
Option 3
If you don't like both above options you have another way of doing it. In my last work (Taskin, if you want to take a look you can see the link in my profile) I needed to show different colors for different ListViewItems. I didn't want to create a new Property in my Task model to hold the color or a TemplateSelector just for this. So I created a simple IValueConverter instead that uses an already existent Priority object property and returns its color. Then I binded it like this:
<Border Background="{Binding Priority, Converter={StaticResource priorityToColorConverter}}"/>
XAML gives you many ways to implement what you want and it is up to you to choose the best and cleanest way to solve the problem you are facing.

How to customize the TextBlock inside the LonglistSelector

<toolkit:LongListSelector>
<toolkit:LongListSelector.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Name}" FontSize="22" TextWrapping="Wrap" />
<TextBlock Name="Info" FontSize="18" TextWrapping="Wrap" />
</StackPanel>
</DataTemplate>
</toolkit:LongListSelector.ItemTemplate>
</toolkit:LongListSelector>
I have the above LongListSelector which selects the "Name"(Binded in the first Textblock )values from a list. I also wanted to additional text to it,for which i created one more Textblock below that. I couldn't add the text to the second TextBlock like(Info.Text="HI") because it is inside the LonglistSelector
How to give the values to the second Textblock??
Thanks
Do you mean Info is a property on the DataContext of the page and not on the current item where Name is?
If so, you can use a DataContextProxy to get to the data outside of the list item. If not, you'll have to be more clear on what you mean.