Bind checkbox to label fontweight with value converter - c#

I want to make label that have FontWeight attribute dependent on checkbox.
If checkbox is checked then label font weight is bold, if not - then font weight is normal. I decided to bind FontWeight attribute in Label with Checkbox and add converter.
Here is screen what I want to achieve (text on bottom should be bolded when Bold is checked)
enter image description here
I created all the logic and binding but when I click on Bold checkbox nothing happends.
Here is what I have so far
MainWindow.xaml
<Window ...
...
<Window.Resources>
<local:BoolToStringConverter x:Key="custom" TrueValue="Bold" FalseValue="Normal" />
</Window.Resources>
<Grid>
...
<CheckBox Name="BoldField" Margin="5" FontWeight="Bold">Bold</CheckBox>
<Label Name="text" Grid.Row="3" Grid.ColumnSpan="3"
FontWeight="{Binding BoldField, Converter={StaticResource custom}}" />
...
</Window>
MainWindow.xaml.cs
namespace Wpf03
{
public class BoolToValueConverter<T> : IValueConverter
{
public T FalseValue { get; set; }
public T TrueValue { get; set; }
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (value == null)
return FalseValue;
else
return (bool)value ? TrueValue : FalseValue;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return value != null ? value.Equals(TrueValue) : false;
}
}
public class BoolToStringConverter : BoolToValueConverter<FontWeight> { }
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
}
}
I tried with different converters but no result. Why my converter is never called? Any ideas?

You are passing the Name of the CheckBox as the Binding Path
instead you need to specify the IsChecked property:
<CheckBox Name="BoldField" Margin="5" FontWeight="Bold">Bold</CheckBox>
<Label Name="text" Grid.Row="3" Grid.ColumnSpan="3"
FontWeight="{Binding ElementName=BoldField, Path=IsChecked, Converter={StaticResource custom}}" />

Related

Dynamically change the color of listbox items in code behind(WPF)

I have a traffic application. The light status is updated in the listbox.
<ListBox x:Name="lbxCallProgress" ItemsSource="{Binding Messages,Mode=TwoWay}" Height="373" FontSize="8" ScrollViewer.VerticalScrollBarVisibility="Visible">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding}"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
For the Messages:
public partial class MainWindow : Window
{
public ObservableCollection<string> Messages { get; set; }
To update messages to the listbox.
void UpdateMessage(string message)
{
try
{
Dispatcher.BeginInvoke((Action)delegate()
{
Dispatcher.BeginInvoke(new Action(() => { this.Messages.Add(message); }));
});
}
Now if the string message contains the keyword "green", then I want to set the item color on the listbox as color green, etc.
How?
here you go
with the power of WPF binding you can use the value to bind to the desired property Background and the implicit converter will do the rest for you.
<DataTemplate>
<TextBlock Text="{Binding}" Background="{Binding}"/>
</DataTemplate>
you can choose to bind Foreground in case if you want to change the text color
Using converters
if simple binding is not sufficient enough you may use converters to perform custom logic of conversion, eg converting The light is red to Brushes.Red
public class MyColorConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
string text = value as string;
if(text.Contains("red"))
return Brushes.Red;
return Brushes.White;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return DependencyProperty.UnsetValue;
}
}
usage
<DataTemplate xmlns:l="your namespace to converter class">
<DataTemplate.Resources>
<l:MyColorConverter x:Key="MyColorConverter" />
</DataTemplate.Resources>
<TextBlock Text="{Binding}" Background="{Binding Converter={StaticResource MyColorConverter}}"/>
</DataTemplate>

Binding radio button to enum property

I think I've followed the examples given in this post but my property is not changing when button are changed. Any suggestions on where I went wrong?
C# code for enum and class
public enum SystemTypes
{
TypeA,
TypeB
}
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
SystemTypes systemType = SystemTypes.TypeA;
public SystemTypes SystemType
{
get { return systemType; }
set { systemType = value; }
}
}
public class EnumToBooleanConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return value.Equals(parameter);
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return value.Equals(true) ? parameter : Binding.DoNothing;
}
}
xaml
<Canvas>
<Canvas.Resources>
<local:EnumToBooleanConverter x:Key="EnumToBooleanConverter" />
</Canvas.Resources>
<RadioButton x:Name="TypeARadioButton" Content="TypeA" Canvas.Left="10" Canvas.Top="10"
IsChecked="{Binding Path=SystemType, Converter={StaticResource EnumToBooleanConverter}, ConverterParameter={x:Static local:SystemTypes.TypeA}}" />
<RadioButton x:Name="TypeBRadioButton" Content="TypeB" Canvas.Left="10" Canvas.Top="31"
IsChecked="{Binding Path=SystemType, Converter={StaticResource EnumToBooleanConverter}, ConverterParameter={x:Static local:SystemTypes.TypeB}}" />
</Canvas>
You need to set Binding Mode to TwoWay, then in Converter implement method ConvertBack responsible for converting bool to SystemTypes, in settter of SystemType include
set { systemType = value; OnPropertyChanged(() => "SystemType");}
in order to fill property in that its value was changed.
OnPropertyChanged(() => "SystemType")
can work if you implement interface INotifyPropertyChanged. I cannot you whether you set DataContext, if you did not binding is not working. In order to rectify this after InitializeComponent() add
this.DataContext = this;

localize language tag to display name converter

I want to convert the localization meta tag e.g. en-US to the display name, in this case English. The meta tag is stored in a ObservableCollection because it will be modified on runtime. I want to bind the display name to a combo box.
ComboBox:
<ComboBox Grid.Column="1" Grid.Row="1" Width="200" VerticalAlignment="Center" HorizontalAlignment="Center" SelectedIndex="0" ItemsSource="{Binding Path=ServerData.AvailableTemplateLanguages}">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding, Converter=LanguageTagToNameConverter}" FontSize="12"/>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
Converter:
class LanguageTagToNameConverter : IValueConverter
{
public object Convert(object value,
Type targetType,
object parameter,
CultureInfo culture)
{
return CultureInfo.GetCultureInfo(value.ToString()).DisplayName;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
ObservableCollection:
public class ServerDataObj : ModelBase
{
private ObservableCollection<string> _availableTemplateLanguages = new ObservableCollection<string> { "de-DE", "en-US" };
public ObservableCollection<string> AvailableTemplateLanguages
{
get
{
return _availableTemplateLanguages;
}
set
{
_availableTemplateLanguages = value;
OnPropertyChanged("AvailableTemplateLanguages");
}
}
}
Unfortunately this approach does not work.
You need to put converter into resources:
<Window>
<Window.Resources>
<LanguageTagToNameConverter x:Key="convLang"/>
</Window.Resources>
...
<TextBlock Text="{Binding, Converter={StaticResource convLang}}"/>

How to Implement a BoolToVisibilityConverter

In my app I would like to toggle the visibility of an item in a StackPanel. My Stackpanel contains an Image and a TextBlock. How would I properly use a BoolToVisibilityConverter to toggle the visibility of the TextBlock, and save this setting for the users benefit?
Currently what I have is as follows, although I am getting a few errors. Important note, I need to use an ApplicationBar menu item as the click event that drives the toggling of the TextBox visibility.
EDIT
Error no longer occurring although the visibility of the TextBlock is not changing.
XAML
xmlns:common="clr-namespace:TestApp.Common"
<phone:PhoneApplicationPage.Resources>
<common:BooleanToVisibilityConverter x:Key="BoolToVisConv" />
</phone:PhoneApplicationPage.Resources>
<ListBox Name="ListBoxEffects" SelectionMode="Single" ItemsSource="{Binding}" Margin="{Binding}"
toolkit:TiltEffect.IsTiltEnabled="True" SelectionChanged="ListBox_SelectionChanged"
ItemContainerStyle="{StaticResource ListBoxItemStyle1}">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<toolkit:WrapPanel ItemWidth="159" ItemHeight="Auto" />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Vertical" >
<Image Source="{Binding Thumbnail}" Width="155" Height="155" />
<TextBlock Text="{Binding Name}" Visibility="{Binding IsTextBlockVisible, Converter={StaticResource BoolToVisConv}}" TextWrapping="Wrap" FontSize="{StaticResource PhoneFontSizeNormal}" VerticalAlignment="Center" HorizontalAlignment="Center" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Code Behind
private void BuildLocalizedApplicationBar()
{
ApplicationBar = new ApplicationBar();
ApplicationBarMenuItem showFilterNamesMenuItem = new ApplicationBarMenuItem();
if (Settings.ShowFilterNames.Value)
showFilterNamesMenuItem.Text = AppResources.EditPage_EffectNames_Hide;
else
showFilterNamesMenuItem.Text = AppResources.EditPage_EffectNames_Show;
showFilterNamesMenuItem.Click += showFilterNamesMenuItem_Click;
ApplicationBar.MenuItems.Add(showFilterNamesMenuItem);
}
void showFilterNamesMenuItem_Click(object sender, EventArgs e)
{
if(Settings.ShowFilterNames.Value)
{
((ApplicationBarMenuItem)ApplicationBar.MenuItems[0]).Text = AppResources.EditPage_EffectNames_Hide;
Settings.ShowFilterNames.Value = false;
//Toggle the text block visibility to here
}
else
{
((ApplicationBarMenuItem)ApplicationBar.MenuItems[0]).Text = AppResources.EditPage_EffectNames_Show;
Settings.ShowFilterNames.Value = true;
//Toggle the text block visibility to here
}
}
A class for the BooleanToVisibilityConverter
//Error on BooleanToVisibilityConverter stating does not implement interface member 'System.Windows.Data.IValueConverter.Convert(object, System.Type, object, System.Globalization.CultureInfo)
public class BooleanToVisibilityConverter : IValueConverter
{
public class BooleanToVisibilityConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo language)
{
return (value is bool && (bool)value) ? Visibility.Visible : Visibility.Collapsed;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo language)
{
return value is Visibility && (Visibility)value == Visibility.Visible;
}
}
Try this:
public class BooleanToVisibilityConverter : IValueConverter
{
private object GetVisibility(object value)
{
if (!(value is bool))
return Visibility.Collapsed;
bool objValue = (bool)value;
if (objValue)
{
return Visibility.Visible;
}
return Visibility.Collapsed;
}
public object Convert(object value, Type targetType, object parameter, string language)
{
return GetVisibility(value);
}
public object ConvertBack(object value, Type targetType, object parameter, string language)
{
throw new NotImplementedException();
}
}
Here is mine:
public class BoolToVisConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, string language)
{
return (value is bool && (bool)value) ? Visibility.Visible : Visibility.Collapsed;
}
public object ConvertBack(object value, Type targetType, object parameter, string language)
{
return value is Visibility && (Visibility)value == Visibility.Visible;
}
}
There is already an implemenation of the converter: http://msdn.microsoft.com/en-us/library/system.windows.controls.booleantovisibilityconverter(v=vs.110).aspx

Binding with ValueConverter to object in another window

I have a main program window with a row of shortcut buttons along the bottom. I'm trying to make the Visibility of these selectable through a separate Settings window using CheckBoxes, and then store that state in the UserSettings of the program so when it's opened again the previous setting will be remembered. I've found and used an IValueConverter to implement this, and I know the Setting is saved as the CheckBox itself retains it's value.
The problem is that clicking the CheckBox does not affect the Visibility of the button. It works within the Settings window itself, but I can't seem to figure out how to make it work between different windows.
I have tried implementing both the UpdateSourceTrigger & NotifyOnSourceUpdated flags to no avail. Can anybody see the problem?
Main Window XAML
<WrapPanel.Resources>
<main:BooleanToHiddenVisibility x:Key="boolToVis" />
</WrapPanel.Resources>
<ToggleButton Name="alwaysOnTop" Checked="alwaysOnTop_Checked"
Style="{StaticResource ShortcutToggleStyle}" Unchecked="alwaysOnTop_Unchecked"
Visibility="{Binding Source=main:Properties.Settings.Default, Path=pinShow, Converter={StaticResource boolToVis}, Mode=TwoWay}" >
<Image SnapsToDevicePixels="True" Source="Images/pushpin.png"
ToolTip="Always on Top" />
</ToggleButton>
Settings Window XAML
<CheckBox Name="pinDisable" Grid.Column="0" Grid.Row="1" HorizontalAlignment="Center"
IsChecked="{Binding Source={x:Static main:Properties.Settings.Default}, Path=pinShow, Mode=TwoWay}"
Checked="pinDisable_Checked" Unchecked="pinDisable_Unchecked"/>
Convertere Code-Behind
public class BooleanToHiddenVisibility : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
Visibility rv = Visibility.Visible;
try
{
var x = bool.Parse(value.ToString());
if (x)
{
rv = Visibility.Visible;
}
else
{
rv = Visibility.Collapsed;
}
}
catch (Exception)
{
}
return rv;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return value;
}
}

Categories