I have two radio buttons with Right and Left options:
<RadioButton Content="Right" Margin="5" VerticalAlignment="Center" IsChecked="{Binding Path=Direction, Mode=TwoWay, Converter={StaticResource EnumConverter}, ConverterParameter=Right}"/>
<RadioButton Content="Left" Margin="5" VerticalAlignment="Center" IsChecked="{Binding Path=Direction, Mode=TwoWay, Converter={StaticResource EnumConverter}, ConverterParameter=Left}"/>
The following Enum to Boolean converter code
public class EnumBooleanConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
string parameterString = parameter as string;
if (parameterString == null)
return DependencyProperty.UnsetValue;
if (Enum.IsDefined(value.GetType(), value) == false)
return DependencyProperty.UnsetValue;
object parameterValue = Enum.Parse(value.GetType(), parameterString);
return parameterValue.Equals(value);
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
string parameterString = parameter as string;
if (parameterString == null)
return DependencyProperty.UnsetValue;
return Enum.Parse(targetType, parameterString);
}
}
Now when I select the radio button Right, the Left option shows error( a red border arround the radiobutton control with Left); and vise versa
how to fix this?
Found the solution, adding it just in case anyone needs.
Problem is, it is trying to pick the validation style from the application.
So I have to decorate the each element of the Radio button it with
Validation.ErrorTemplate="{x:Null}"
Thanks!
Related
I have a group of radio buttons all connected up to the same variable in the viewmodel
<RadioButton Content="20" Margin="5,0" GroupName="open_rb"
IsChecked="{Binding Path=mOpen.Threshold, Mode=OneWayToSource, Converter={StaticResource RadioBoolToIntConverter}, ConverterParameter=20, UpdateSourceTrigger=PropertyChanged}" />
<RadioButton Content="50" Margin="5,0" GroupName="open_rb"
IsChecked="{Binding Path=mOpen.Threshold, Mode=OneWayToSource, Converter={StaticResource RadioBoolToIntConverter}, ConverterParameter=50, UpdateSourceTrigger=PropertyChanged}"/>
<RadioButton Content="70" Margin="5,0" GroupName="open_rb"
IsChecked="{Binding Path=mOpen.Threshold, Mode=OneWayToSource, Converter={StaticResource RadioBoolToIntConverter}, ConverterParameter=70, UpdateSourceTrigger=PropertyChanged}"/>
And my converter is -
public class RadioBoolToIntConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
//should not hit this part
int integer = (int)value;
if (integer == int.Parse(parameter.ToString()))
return true;
else
return false;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
//bool to int (if bool is true then pass this val)
bool val = (bool)value;
if (val == true)
return UInt32.Parse(parameter as string);
else
{
//when you uncheck a radio button it fires through
//isChecked with a "false" value
//I cannot delete this part, because then all code paths will not return a value
return "";
}
}
}
Basically the idea is that if a certain radio button is clicked, the converter passes 20 or 30 or 70 (depends upon which radio button is clicked) to mOpen.Threshold which is an unsigned int.
Now, the radiobutton "isChecked" event gets triggered if the radio button is checked or not, with values of true and false. Now, if it's false, I return an empty string from the converter which doesn't parse to uint and causes the UI to complain.
Is it possible to only use this converter if the radio button is checked? Which implies that for this group, if I click a radio button, this converter should only be fired once, not twice.
Using this approach it seems like you only want to set the source property when any of the IsChecked properties are set to true. You can then return Binding.DoNothing when val is false:
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
//bool to int (if bool is true then pass this val)
bool val = (bool)value;
if (val == true)
return UInt32.Parse(parameter as string);
return Binding.DoNothing;
}
I have one Enum Description Converter
public class EnumDescriptionConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
//// parameter need current item, but null or "Value"
if (Enum.IsDefined(value.GetType(), value) == false)
return System.Windows.DependencyProperty.UnsetValue;
string parameterString = Enum.GetName(value.GetType(), value);
if (parameterString == null)
return System.Windows.DependencyProperty.UnsetValue;
var desc = (value.GetType().GetField(parameterString).GetCustomAttributes(typeof(DescriptionAttribute), false).FirstOrDefault() as DescriptionAttribute);
if (desc != null)
return desc.Description;
else
return parameter.ToString();
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
i like to Pass current combobox item to converter as ConverterParameter
<ComboBox Name="test" Grid.Column="1" Grid.Row="2" VerticalAlignment="Center" IsReadOnly="True" >
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Converter={StaticResource enumDescriptionConverter},ConverterParameter=Value}"/>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
but Value is coming as string "Value", when i try binding getting error. Is any way to pass current item ?
You don't need a converter parameter for this. Simply replace:
value.GetType().GetField(parameterString)
with
value.GetType().GetField(value.ToString())
You can get rid of parameterString entirely. The string representation of a singular enum value always matches the field name for that value (or, in cases where multiple enum elements have the same value, it will match the field name for an equivalent value).
I have a listbox that is populated from a datatable. I want each item to have a specific image on listbox, but I want to set the image depending of an id that each item has.
for example , I have :
Products
Orange
Apple
ID
1
2
and the images are named: Item.1.png , Item.2.png
So, in my listbox,where I have apple, I will have next to it the image named: Item.2.png.
My problem is that I don't know how could I do a conditional binding . I don't want to have on my template hundreds of lines that are doing this for each item. I need to do this using a condition, like : if(product.id==1), Image.Source=Item.1.png.
Is there any way to do this in wpf?
It sounds to me like you need an IdToImageConverter that will decides which Image should be shown dependant on the value of the Id property. Something like this should do the trick:
[ValueConversion(typeof(int), typeof(ImageSource))]
public class IdToImageConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value.GetType() != typeof(int) || targetType != typeof(ImageSource)) return false;
int id = (int)value;
if (id < 0) return DependencyProperty.UnsetValue;
string imageName = string.Empty;
switch (id)
{
case 1: imageName = "Item.1.png"; break;
case 2: imageName = "Item.2.png"; break;
}
if (imageName.IsEmpty()) return null;
return string.Format("/AppName;component/ImageFolderName/{0}", imageName);
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return DependencyProperty.UnsetValue;
}
You could then use it in your ListBox.ItemTemplate something like this:
<YourConvertersXmlNamespacePrefix:IdToImageConverter x:Key="IdToImageConverter" />
...
<ListBox ItemsSource="{Binding Items}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Image Source="{Binding Id, Converter={StaticResource
IdToImageConverter}}" />
<TextBlock Text="{Binding Name}" Margin="5,0,0,0" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
As I understand your question, every object in the listbox has an ID property, where you want the image to be item.ID.png.
You could use a converter in your binding to do this. So in your listbox template, you can have something like:
// ... Listbox template
<Image Source={Binding pathToItemID, Converter={StaticResource MyConverter}/>
// ... Remaining ListBox template
You will need to add the converter to the UserControl's resources:
<UserControl.Resources>
<xmlnsPointingToConverter:MyConverter x:Key="MyConverter"/>
</UserControl.Resources>
Then add a MyConverter class which implements IValueConverter:
public class MyConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return string.Format("item.{0}.png", value);
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
Hear i Have a confusion while Binding the data to Text Block in Windows phone
I have Text Block
<TextBlock Name="strytxt"
Text="{Binding STORY}"
Height="auto"
Width="Auto"
TextWrapping="Wrap"/>
in STORY Object some time I have Empty/Null Values
At that Time im Getting Some space in my UI
Now i Want to Make Visibility of the Textbox in to Collapsed if i get Null in that row
How can i do this
To change the Visibility of the TextBlock when the Binding value is null you need to use a Converter that converts from null/not null to Visible/Collapsed.
HereĀ“s a converter that converts the values. The converter handles an empty string as null, so that it return Collapsed for string.empty.:
public class NullToVisibilityConverter : IValueConverter {
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) {
bool isVisible = value == null ? false : true;
if (isVisible) {
string stringValue = value as string;
if (stringValue != null) {
isVisible = string.IsNullOrEmpty(stringValue) ? false : true;
}
}
if (System.ComponentModel.DesignerProperties.IsInDesignTool) {
return Visibility.Visible;
}
return isVisible ? System.Windows.Visibility.Visible : System.Windows.Visibility.Collapsed;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) {
throw new NotImplementedException();
}
}
You can apply the converter to the TextBlock as follows:
<UserControl.Resources>
<local:NullToVisibilityConverter x:Key="NullToVisibilityConverter"/>
</userControl.Resources>
<TextBlock Name="strytxt"
Visibility="{Binding STORY, Converter={StaticResource nullToVisibilityConverter}}"/>
Another alternativ is to display a Text when the value is null, you can specify that in the binding
<TextBlock Name="strytxt"
Text="{Binding STORY, TargetNullValue='is Null'}"/>
You can use a value converter to convert the value to a visibility:
public class NullToVisibiltyConverter : IValueConverter {
public Object Convert(Object value, Type targetType, Object parameter, CultureInfo culture) {
return value == null ? Visibility.Collapsed : Visibility.Visible;
}
public Object ConvertBack(Object value, Type targetType, Object parameter, CultureInfo culture) {
throw new NotImplementedException();
}
}
You then bind the Visibility of the TextBlock using the converter:
<TextBlock Name="strytxt"
Text="{Binding STORY}"
Height="auto"
Width="Auto"
TextWrapping="Wrap"
Visibility="{Binding STORY, Converter={StaticResource NullToVisibilityConverter}}"/>
You need to add an instance of the converter to a resource dictionary to be able to reference it in the binding:
<UserControl.Resources>
<local:NullToVisibilityConverter x:Key="NullToVisibilityConverter"/>
</userControl.Resources>
I am using WPF.
I want to show button when the label is not empty. When Label has a value, the button will be hidden.
How can I do this with WPF? Using <Style>?
Code:
<Label Name="lblCustomerName"/>
<Button Name="btnCustomer" Content="X" Visibility="Hidden" />
try
if (string.IsNullOrEmpty(lblCustomerName.Text)) {
btnCustomer.Visibility = Visibility.Hidden;
}
else {
btnCustomer.Visibility = Visibility.Visible;
}
You will need to use a converter and bind it to the content of lblCustomer.
public class ContentNullToVisibilityConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value == null)
{
return Visibility.Hidden;
}
return Visibility.Visible;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
More on converters here.
Then in xaml you can do the following:
First line needs to be defined in your resources where you will need to qualify it with the namespace in which you created the class above. Once you have defined the resource you can use the second part.
<ContentNullToVisibilityConverter x:Key="visConverter"/>
<Label Name="lblCustomerName"/>
<Button Name="btnCustomer" Content="X" Visibility="{Binding ElementName=lblCustomer, Path=Content, Converter={StaticResource visConverter}}" />