Visibility binding - wpf

I have this situation:
<TextBlock x:Name="NoMonthDataTextBlock"
Text="No data."
Margin="20,10,0,0"
Foreground="Black"
FontWeight="Bold"
FontSize="20"
Visibility="{Binding SelectedSymbolItem.NoData, Converter={StaticResource FieldVisible}}"/>
<tools:BoolToVisibilityConverter x:Key="FieldVisible" TrueValue="Visible" FalseValue="Collapsed" />
public class BoolToVisibilityConverter : BoolToValueConverter<Visibility>
{
}
public class BoolToValueConverter<T> : IValueConverter
{
public T FalseValue { get; set; }
public T TrueValue { get; set; }
public object Convert(object value, Type targetType, object parameter, string language)
{
if (value == null)
return FalseValue;
else
return (bool)value ? TrueValue : FalseValue;
}
public object ConvertBack(object value, Type targetType, object parameter, string language)
{
return value != null ? value.Equals(TrueValue) : false;
}
}
The problem is when the SelectedSymbolItem is null the field is visible and I don't want that.
I want this textBlock to be visible only when the SelectedSymbolItem is not null and has empty data.
I have thought about using Multibing but I'm targeting windows store apps(8.0) and is not supported here. (one condition for not null and another for no data.)
How can I make the textBlock to be Collapsed when SelectedSymbolItem is null?

Put a FallbackValue of Collapsed ,
in your case this would work there would be a Binding error on the Visibility Property and it will take the supplied FallbackValue.
<TextBlock x:Name="NoMonthDataTextBlock"
Text="No data."
Margin="20,10,0,0"
Foreground="Black"
FontWeight="Bold"
FontSize="20"
Visibility="{Binding SelectedSymbolItem.NoData,Converter={StaticResource FieldVisible},FallbackValue=Collapsed}"/>
<tools:BoolToVisibilityConverter x:Key="FieldVisible" TrueValue="Visible" FalseValue="Collapsed" />

Related

ValueConverter for Background Color

I have a Forecast class. One of the field's type is Enum:
enum GeneralForecast
{
Sunny,
Rainy,
Snowy,
Cloudy,
Dry
}
class Forecast
{
public GeneralForecast GeneralForecast { get; set; }
public double TemperatureHigh { get; set; }
public double TemperatureLow { get; set; }
public double Percipitation { get; set; }
}
I display list of forecasts on the ListBox and I want to set the BackgroundColor of the item in the ListBox depend on GeneralForecast.
So I have created Converter:
class GeneralForecastToBrushConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, string language)
{
var gf = (GeneralForecast) value;
switch (gf)
{
case GeneralForecast.Cloudy:
return "FF1D1D1D";
case GeneralForecast.Dry:
return "55112233";
case GeneralForecast.Rainy:
return "88FF5522";
case GeneralForecast.Snowy:
return "9955FF22";
case GeneralForecast.Sunny:
return "FF11FF99";
}
return "FFFFFFFF";
}
public object ConvertBack(object value, Type targetType, object parameter, string language)
{
throw new NotImplementedException();
}
}
Here is my XAML:
<Page.Resources>
<local:GeneralForecastToBrushConverter x:Key="gf2color"/>
</Page.Resources>
<ListBox ItemsSource="{Binding}" Grid.Row="2" HorizontalAlignment="Stretch">
<ListBox.ItemTemplate>
<DataTemplate>
<Border Margin="4" BorderBrush="Black" Padding="4"
BorderThickness="2"
Background="{Binding GeneralForecast, Converter={StaticResource gf2color}}">
<StackPanel Orientation="Horizontal">
<TextBlock FontSize="20" FontWeight="Bold"
Text="{Binding GeneralForecast}"/>
</StackPanel>
</Border>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
If I debug my Converter I can see that it returns different colors, but I have all items the same color. Why ?
When you write something like this in XAML:
<Button Background="#FF11111" />
The Xaml parser will convert that string to its equivalent color at runtime.
But when you assign color in C# somehow, you may not set the color as string.
Instead you should use something like SolidColorBrush instances.
So return some variable which is Brush, such as solid or gradient color brushes.
Let me know if any other information is needed.

Silverlight datagrid cell edit does not reflect in cell

In this silverlight grid cell, the display value does not update when the edit value is updated, any ideas why?
<sdk:DataGridTemplateColumn Header="Bid Qty" IsReadOnly="True">
<sdk:DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock VerticalAlignment="Center"
HorizontalAlignment="Center"
Text="{Binding Path=BidPrice.Quantity, Mode=OneWay, UpdateSourceTrigger=PropertyChanged, Converter={StaticResource CustomDoubleToStringConverter}}"
Foreground="{Binding Path=BidPrice.TextColour}"
ToolTipService.ToolTip="{Binding Path=BidPrice.ToolTip}"
ToolTipService.Placement="Right" />
</DataTemplate>
</sdk:DataGridTemplateColumn.CellTemplate>
<sdk:DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<TextBox Text="{Binding Path=BidPrice.Quantity, Mode=TwoWay, Converter={StaticResource CustomDoubleToStringConverter}}" />
</DataTemplate>
</sdk:DataGridTemplateColumn.CellEditingTemplate>
</sdk:DataGridTemplateColumn>
Code (very simplified) :
// field is bound to BidPrice on this
public class PriceStackLine : INotifyPropertyChanged
{
public ProductPrice BidPrice { get; set; }
}
// BidPrice is a ProductPrice with a Quantity property
public class ProductPrice : INotifyPropertyChanged
{
private double _qty;
public double Quantity
{
get
{
return _qty;
}
set
{
_qty = value;
NotifyPropertyChanged("Quantity");
}
}
public event PropertyChangedEventHandler PropertyChanged;
public void NotifyPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
// converter
public class CustomDoubleToStringConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
double num = (double)value;
if (num == 0)
return string.Empty;
return num;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
double result = 0;
double.TryParse(value.ToString(), out result);
return result;
}
}
UPDATE - FIXED! The TextColour was null on the new edits which was probably defaulting to transparent, that is why I couldnt see the edit

Silverlight implement value converter to comboBox

I have the following scenario
1- A combobox in xaml
<ComboBox
x:Name="PublishableCbo" Width="150" IsEnabled="True" HorizontalAlignment="Left" Height="20"
SelectedValue="{Binding Path=Published, Mode=TwoWay}"
Grid.Column="6" Grid.Row="0">
<ComboBox.Items>
<ComboBoxItem Content="All" IsSelected="True" />
<ComboBoxItem Content="Yes" />
<ComboBoxItem Content="No" />
</ComboBox.Items>
2- In a model class, I defined a property and bind to the selectedvalue in combobox
public bool Published
{
get
{
return _published;
}
set
{
_published = value;
OnPropertyChanged("Published");
}
}
I know I have to implement a converter, but don't know exactly how. What I want is when a select Yes/No, in the model get a True/false value, when "all" is selected, to get null value.
In order to be able to assign null to the Published property, you would have to change its type to Nullable< bool > (you can write bool? in C#).
public bool? Published
{
...
}
The Converter could be implemented so that it converts from string to bool and vice versa, perhaps like shown below. Note that the converter uses bool, not bool? since the value is passed to and from the converter as object, and hence boxed anyway.
public class YesNoAllConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
object result = "All";
if (value is bool)
{
result = (bool)value ? "Yes" : "No";
}
return result;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
object result = null;
switch ((string)value)
{
case "Yes":
result = true;
break;
case "No":
result = false;
break;
}
return result;
}
}
To enable the use of this converter, you have to change your ComboBox item type to string, and bind to the SelectedItem property, not SelectedValue.
<ComboBox SelectedItem="{Binding Path=Published, Mode=TwoWay,
Converter={StaticResource YesNoAllConverter}}">
<sys:String>All</sys:String>
<sys:String>Yes</sys:String>
<sys:String>No</sys:String>
</ComboBox>
where sys is the following xml namespace declaration:
xmlns:sys="clr-namespace:System;assembly=mscorlib"

Silverlight 4: how to switch control visibility

I am using MVVM in my Silverlight app. When control visibility is need to be managed by data, I am connecting its 'Visibility' property to object's corresponding property:
XAML:
<TextBlock Text="Price" Visibility="{Binding PriceVisibility, Mode=OneWay}"/>
<TextBox Text="{Binding TicketPrice, Mode=TwoWay}" Visibility="{Binding PriceVisibility, Mode=OneWay}"/>
CodeBehind (C#):
public string PriceVisibility { get { return PriceVisible ? "Visible" : "Collapsed"; } }
But from my perspective, returning string representation of the Visibility property is not a best approach.
Could you please advise if there are any better way?
Thanks!
I just used Reflector to inspect the type converters in the PresentationFramework.dll
There is already an implementation that can convert between boolean and visibility. You should be able to make use of this in your silverlight application.
public sealed class BooleanToVisibilityConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
bool flag = false;
if (value is bool)
{
flag = (bool) value;
}
else if (value is bool?)
{
bool? nullable = (bool?) value;
flag = nullable.HasValue ? nullable.Value : false;
}
return (flag ? Visibility.Visible : Visibility.Collapsed);
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return ((value is Visibility) && (((Visibility) value) == Visibility.Visible));
}
}
I've faced the problem of binding a Boolean value to the visibility property, so I've implemented my own Boolean to Visibility Converter, I'm using it with most of my applications.
Add the Following Class to your application:
public class BoolVisibilityConverter : IValueConverter{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture){
bool isVisible = (bool)value;
return isVisible ? System.Windows.Visibility.Visible : System.Windows.Visibility.Collapsed;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture){
System.Windows.Visibility currVisibility = (System.Windows.Visibility)value;
return (currVisibility == System.Windows.Visibility.Visible);
}
}
Now To Use it you'll need to add it as a resource in your XAML Code.
<UserControl.Resources>
<Helpers:BoolVisibilityConverter x:Key="boolVisibilityConverter" />
</UserControl.Resources>
In your example use the following:
<TextBlock Text="Price" Visibility="{Binding PriceVisibility, Mode=OneWay, Converter={StaticResource boolVisibilityConverter}}"/>
<TextBox Text="{Binding TicketPrice, Mode=TwoWay}" Visibility="{Binding PriceVisibility, Mode=OneWay, Converter={StaticResource boolVisibilityConverter}}"/>

WPF: Binding Visibility by string contents

Ok, so here is my XAML:
<TextBlock Text="{Binding Path=InstanceName}"></TextBlock>
If InstanceName is null or an empty string, I want Visibility="Collapsed". Otherwise I want Visibility="Visible". How would I do that?
You could use a ValueConverter:
<TextBlock
Visibility="{Binding InstanceName, Converter={local:StringNullOrEmptyToVisibilityConverter}}"
Text="{Binding InstanceName}"/>
with the following codebehind:
public class StringNullOrEmptyToVisibilityConverter : System.Windows.Markup.MarkupExtension, IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return string.IsNullOrEmpty(value as string)
? Visibility.Collapsed : Visibility.Visible;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return null;
}
public override object ProvideValue(IServiceProvider serviceProvider)
{
return this;
}
}
If you are inside a (Data-)Template you can use Triggers for that.
Otherwise, the MVVM-Pattern or a ValueConverter will help you.
By putting an extra property in your viewmodel that you can bind the Visibility attribute to:
public class ViewModel
{
public string InstanceName {...}
public Visibility InstanceVisibility
{
get
{
return String.IsNullOrEmpty(InstanceName) ? Visibility.Collapsed : Visibility.Visible;
}
}
<TextBlock Text="{Binding Path=InstanceName},FallbackValue={x:Null}"></TextBlock>
Then add a DataTrigger to check the value is null and change visibility using Setter.
This is the simple method which iam using.
Ok, so this is close with PyBinding:
<TextBlock Text="{Binding Path=InstanceName}" Visibility="{p:PyBinding BooleanToVisibility(IsNotNull($[.InstanceName]))}" ></TextBlock>
I need to replace IsNotNull with something that means IsNotNullOrEmpty, but I'm getting closer.

Resources