We have a UWP app using Template10. There is a textblock and textbox which show a discount. We wish to hide the textblock when ViewModel.Discount is null.
In App.xaml we have defined a converter
<T10Converters:ValueWhenConverter x:Key="HideWhenNullConverter" When="{x:Null}">
<T10Converters:ValueWhenConverter.Value>
<Visibility>Collapsed</Visibility>
</T10Converters:ValueWhenConverter.Value>
<T10Converters:ValueWhenConverter.Otherwise>
<Visibility>Visible</Visibility>
</T10Converters:ValueWhenConverter.Otherwise>
</T10Converters:ValueWhenConverter>
In the View we set the visibility of the TextBlock
Visibility="{x:Bind ViewModel.Discount, Converter={StaticResource HideWhenNullConverter}}"
In the ViewModel:
public class ViewModel : ViewModelBase
{
decimal? _Discount = default(decimal?);
public decimal? Discount
{
get
{
return _Discount;
}
set
{
if (value == 0) value = null;
Set(ref _Discount, value);
}
}
However the textblock is always visible even if the value of ViewModel.Discount is null. How do we hide the textblock when ViewModel.Discount is null
As I've tried with Template10's source it should work. I suspect that you are just missing redefinition of Mode with x:Bind, which as default is OneTime. Try like this:
Visibility="{x:Bind ViewModel.Discount, Mode=OneWay, Converter={StaticResource HideWhenNullConverter}}"
Related
I am trying to hide last Grid column. I'm trying to do it with DataTrigger, this is how my trigger looks like:
<ResourceDictionary>
<Style x:Key="HideLastVerticalLine" TargetType="BoxView">
<Style.Triggers>
<DataTrigger
Binding="{Binding Items, Path=Items.LastOrDefault}"
TargetType="BoxView"
Value="{Binding Items.Length}">
<Setter Property="IsVisible" Value="False" />
</DataTrigger>
</Style.Triggers>
</Style>
</ResourceDictionary>
<BoxView Style="{StaticResource HideLastVerticalLine}" Grid.Column="1" HeightRequest="100" WidthRequest="1" BackgroundColor="Black"/>
I'm applying this DataTrigger to a BoxView, which contains a vertical line separator (I want something as Trim(), just to remove last separator line.
How can I do it?
You can use a DataTemplateSelector to achieve this.
The sample is here.
Create two DataTemplates, one for LastViewCell and one for other ViewCells:
public class PersonDataTemplateSelector : DataTemplateSelector
{
public DataTemplate NormalTemplate { get; set; }
public DataTemplate LastCellTemplate { get; set; }
protected override DataTemplate OnSelectTemplate (object item, BindableObject container)
{
var lastItem = Items.LastOrDefault();
return lastItem = item ? LastCellTemplate : NormalTemplate;
}
}
Choose to use which DataTemplate by checking if the item is last Item.
Create Bindable Layout.
Create separate template selector class.
The class used to populate the bindable layout itemsource must have new property isLast bool.
Update the list with last element as true.
Now Bind this new list with the bindable layout you are using on the view.
Don’t forget to add your templateselector on resource dictionary of that page.
For updating last item in list to isLast = true use.
int index = 0;
foreach (var item in list) // here updating last element of list islast =true
{
item.IsLast = (index == list.Count - 1);
index++;
}
how to change gridview row color based on condition in uwp c#?
I want to highlight the gridview row based on my conditon.
A convenient way to do this would be to put a Border around your GridViewItem and use a ValueConverter to choose the background color based on the current item.
First you define your value converter:
public class ItemToColorConverter: IValueConverter
{
//this converts the item from your data source to the color brush
//of the background of the row
public object Convert(object value, Type targetType,
object parameter, string language)
{
//cast the value parameter to the type of item in your data source
var yourValue = ( YourType )value;
if ( yourValue > 10 ) //some condition you want to use to choose the color
{
//highlight
return new SolidColorBrush( Colors.Green );
}
else
{
//leave no background
return new SolidColorBrush( Colors.Transparent );
}
}
//you don't have to implement conversion back as this is just one-way binding
public object ConvertBack(object value, Type targetType,
object parameter, string language)
{
throw new NotImplementedException();
}
}
Now you need to create a Application resource instance of the converter in App.xaml:
<Application ...>
<Application.Resources>
<converters:ItemToColorConverter x:Key="ItemToColorConverter" />
</Application.Resources>
</Application>
Now use this converter in your GridView item DataTemplate:
<GridView ItemsSource="{Binding YourDataSource"}>
<GridView.ItemTemplate>
<DataTemplate>
<Border Background="{Binding Converter={StaticResource ItemToColorConverter}">
<!-- ... your content -->
</Border>
</DataTemplate>
</GridView.ItemTemplate>
</GridView>
I have a Windows 8.1 application. I have a requirement of selecting different templates based on a certain value. For this purpose I'm using ContentPresenter in the xaml with a Static Resource TemplateSelector.
Here's my datatemplates and templateselector in xaml resources
<DataTemplate x:Key="template1">
<TextBox Text="Temp 1" />
</DataTemplate>
<DataTemplate x:Key="template2">
<TextBox Text="Temp 2" />
</DataTemplate>
<DataTemplate x:Key="template3">
<TextBox Text="Temp 3" />
</DataTemplate>
<template:BalanceTypesTemplateSelector x:Key="MySelector"
Template1="{StaticResource template1}"
Template2="{StaticResource template2}"
Template3="{StaticResource template3}" />
Here's my ContentPresenter XAML
<ContentPresenter ContentTemplateSelector="{StaticResource MySelector}"
Content="{Binding MyData}" />
Here's my Template Selector Code
public class BalanceTypesTemplateSelector : DataTemplateSelector
{
public DataTemplate Template1 { get; set; }
public DataTemplate Template2 { get; set; }
public DataTemplate Template3 { get; set; }
protected override DataTemplate SelectTemplateCore(object item)
{
var type = item.ToString();
switch (type)
{
case "t1":
return Template1;
case "t2":
return Template1;
case "t3":
return Template3;
default:
throw new NotSupportedException();
}
}
return null;
}
}
But it's not hitting the templateselector code at all. The string that is bound is directly displayed on the display when I run the app.
I would be glad if some one point me in the right direction. Thanks in Advance.
Basically, you're only overriding one of the SelectTemplateCore overloads.
From the DataTemplateSelector docs:
To define an effective DataTemplateSelector subclass, provide implementations for SelectTemplateCore(Object) and SelectTemplateCore(Object, DependencyObject)
Once you provide an implementation for SelectTemplateCore(Object, DependencyObject), it will get invoked.
I tried to do it, but there was another problem I encountered - the object is always null (and not the Content/DataContext of the ContentPresenter).
I asked Google why is that and found this discussion. From it:
The ContentControl and ContentPresenter appear to be broken in Windows RT when used with a ContentTemplateSelector property bound to a view model. The 'object' parameter to the template selector is always null.
There's also a workaround for this problem at the end of that discussion.
Hope this helps. :)
Using ContentControl instead of ContentPresenter is working for me. Thanks #KaiBrummund for his comment on my question.
Using Caliburn.Micro for a WinRT application, I would like to control the ZIndex of items displays in an ItemsControl.
When a user taps on an item, it should become the topmost element.
<ItemsControl Background="White" Height="auto" Width="auto" x:Name="Parts"
HorizontalAlignment="Left"
VerticalAlignment="Top"
>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas></Canvas>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
The viewmodel bound to the view above contains a property Parts:
private BindableCollection<IPartViewModel> _parts = new BindableCollection<IPartViewModel>();
public BindableCollection<IPartViewModel> Parts
{
get { return _parts; }
set { _parts = value; NotifyOfPropertyChange(() => Parts); }
}
IPartViewModel has different implementations, each with their own View (= custom user controls).
Every implementation of IPartViewModel has a ZIndex property, ready to be bound.
All other bindings (labels, the tapped event, ...) work perfectly, but I cannot figure out what the binding should look like to control the ZIndex.
Many other questions on SO deal with this issue, but none for WinRT.
I ended up achieving this with a custom ItemsControl and overriding the method GetContainerForItemOverride where I return a ContentPresenter with a binding added to the ZIndex property
protected override DependencyObject GetContainerForItemOverride()
{
var cp = new ContentPresenter();
cp.SetBinding(Canvas.ZIndexProperty, new Binding { Path = new PropertyPath("ZIndex") });
return cp;
}
Hard to put into words for title. I have a normal WPF combo box and the data (list of names) is getting pulled from SQL and I want to change the text colour and
Foreground ="Black"
only seems to be working when I actually select the user. Any suggestions how else I can change this?
EDIT: I haven't tried any other things as of yet as I know that way to actually change the text colour.
EDIT2:
<ComboBox x:Name="cmbDepartment" HorizontalAlignment="Left" Height="25" Margin="92,580,0,0" VerticalAlignment="Top" Width="400" Foreground="#FFA2A2A2" FontSize="13"/>
This is my XAML code for the combo box. I have figured out that my theme is making it blue but when I change the font colour on my theme everything then turns that colour in my application. Is there a piece of code that I can write in my XAML which will set the colour of everything in the combo box grey, without changing the colours in my application.
I assume that initially the ComboBox shows no selected value and once you click on it it shows the list of names with the proper color (being whatever color you assigned through the Foreground property).
If so, may it be the case that you haven't selected an item? Once you have set the items, you must select an item (e.g. SelectedIndex, SelectedValue) if you don't want the ComboBox selection to appear empty.
Excuse me if this is not the case, but the question was pretty vague..
Here is a example using MVVM
XAML
<Window x:Class="SelfBinding.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<ComboBox ItemsSource="{Binding MyItems}">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Name}" Foreground="{Binding Name}"/>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
</Grid>
</Window>
codebehind
using System.Collections.Generic;
using System.Windows;
namespace SelfBinding
{
/// <summary>
/// Interaktionslogik für MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
DataContext = new MyViewModel();
}
}
public class MyViewModel
{
public List<MyItem> MyItems { get; set; }
public MyViewModel()
{
MyItems = new List<MyItem>();
MyItems.Add(new MyItem { Name = "Black" });
MyItems.Add(new MyItem { Name = "Red" });
MyItems.Add(new MyItem { Name = "Orange" });
MyItems.Add(new MyItem { Name = "Green" });
}
}
public class MyItem
{
public string Name { get; set; }
}
}
to test it on your on create a new WPFproject an copy & past the code
Maybe you can override the theme colors in the combobox resources. This is an exaple for doing so.
I just don't know what exactly is the key that you need to override. I guess you can google that.
good luck.