I have a combobox with StaticResource called Currencies, Currencies is an ObservableCollection of some class
in this class i have a parameter called CurrencyID.
I have another class called Item which have a parameter called CurrencyID.
i want to set the Item.CurrencyID from the combobox, for that i use ValueSelected and ValueSelectedPath with a converter from comboboxitem to the CurrencyID.
and it works.
next i want to select the comboboxitem from the CurrencyID of the Item class.
But it always show unselected comboboxitem.
Here's the relevant code:
XAML:
<Window.Resources>
<converters:sp_GetCurrencies_ResultToID x:Key="sp_GetCurrencies_ResultToIDConverter"/>
<CollectionViewSource x:Key ="Currencies" Source="{Binding Currencies}"/>
</Window.Resources>
<ComboBox x:Name="cmbCurrencies" ItemsSource="{Binding Source={StaticResource Currencies} }" SelectedValuePath="{Binding CurrencyID, Mode=TwoWay}" SelectedValue="{Binding Item.CurrencyID, Converter={StaticResource sp_GetCurrencies_ResultToIDConverter}}" DisplayMemberPath="CurrencyName" Width="150" Height="30" VerticalContentAlignment="Center" FlowDirection="RightToLeft" VerticalAlignment="Top" HorizontalAlignment="Right" Margin="5"/>
Converter:
public class sp_GetCurrencies_ResultToID : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (value != null)
using (PricingManagerEntities db = new PricingManagerEntities())
return db.sp_GetCurrencies((long)value,null).FirstOrDefault();
else
return null;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (value != null)
{
return (value as sp_GetCurrencies_Result).CurrencyID;
}
else return null;
}
}
Inside the code i set Item.CurrencyID = 1.
I'm getting also this error, in which i think it's related:
BindingExpression path error: 'CurrencyID' property not found on 'object' ''ItemsViewModel' (HashCode=45202739)'. BindingExpression:Path=CurrencyID; DataItem='ItemsViewModel' (HashCode=45202739); target element is 'ComboBox' (Name='cmbCurrencies'); target property is 'SelectedValuePath' (type 'String')
The program '[12436] PricingManager.vshost.exe' has exited with code 0 (0x0).
Thank you for your help.
Related
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).
Everytime i change my selected item inside my UI it's not updating my combobox.
XAML
<ComboBox x:Name="CompanyComboBox" HorizontalAlignment="Left" Height="26"
Margin="100,41,0,0" VerticalAlignment="Top" Width="144"
SelectionChanged="CompanyComboBox_SelectionChanged"
SelectedItem="{Binding SelectedCompany, UpdateSourceTrigger=PropertyChanged, Mode=OneWayToSource}">
<ComboBox.ItemTemplate>
<DataTemplate>
<ContentPresenter
Content="{Binding Converter={StaticResource DescriptionConverter}}">
</ContentPresenter>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
C#
private Company _selectedCompany;
public Company SelectedCompany
{
get { return _selectedCompany; }
set
{
if (value == _selectedCompany)
return;
_selectedCompany = value;
OnPropertyChanged(nameof(SelectedCompany));
}
}
Just to clarify the Company class is actually an ENUM
DescriptionConverter:
public class CompanyDescriptionConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var type = typeof(Company);
var name = Enum.GetName(type, value);
FieldInfo fi = type.GetField(name);
var descriptionAttrib = (DescriptionAttribute)
Attribute.GetCustomAttribute(fi, typeof(DescriptionAttribute));
return descriptionAttrib.Description;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotSupportedException();
}
}
what i mean by inside my UI, is i have a list of companies set to a combobox item source, and when i change the combobox value to another company, it doesn't update in my source, it stay's as default.
My Enum might clarify the problem for someone:
[Description("Netpoint Solutions")]
Company1 = 0,
[Description("Blackhall Engineering")]
Company2 = 180,
Try to remove Mode=OneWayToSource and your event handler:
SelectionChanged="CompanyComboBox_SelectionChanged"
You don't need to handle the SelectionChanged event when you bind the SelectedItem property.
Also make sure that you set the DataContext to an instance of your class where the SelectedCompany property is defined.
Your Binding is defined as OneWayToSource. When you want it to be updated from the viewModel, you should set it to TwoWay.
See the documentation of Bindings for more details: https://msdn.microsoft.com/de-de/library/ms752347(v=vs.110).aspx
EDIT:
I skipped the part where you have an Enum as the source. I do not see, that you define the ItemsSource for the Combobox, where is this done? The value passed to the setter of SelectedCompany has to be in the Collection defined as ItemsSource.
For Enums, you can refer to this thread: How to bind an enum to a combobox control in WPF?
How can I bind an inverted value of a bool in my xaml?
I know, I know, there are a lot of q&a about this, but there aren't any about a specific case: when the converter is in a view model and the radio button in a user control.
how can I correctly refer to the main window view model data context? In other case I used the code I've posted, but in this case I don't get how to use it.
UPDATE CODE:
namespace ***.ViewModel
{
[ValueConversion(typeof(bool), typeof(bool))]
public class InverseBooleanConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter,
System.Globalization.CultureInfo culture)
{
if (targetType != typeof(bool))
throw new InvalidOperationException("The target must be a boolean");
return !(bool)value;
}
public object ConvertBack(object value, Type targetType, object parameter,
System.Globalization.CultureInfo culture)
{
throw new NotSupportedException();
}
}
class MainWindowViewModel : MyClass.UtilityClasses.ViewModelBase
{
public MainWindowViewModel(){
SaveCommand = new DelegateCommand(SaveData, CanSave );
UndoCommand = new DelegateCommand(UndoActions, CanSave);
[...]
}
....
}
ANOTHER CODE UPDATE:
In my xaml, I have a devexpress GridControl where I list my observableCollection from db. When I click one element, a layout group is populated with the relative data.
In this layout group, I have:
<StackPanel Margin="0" Orientation="Horizontal" VerticalAlignment="Center" HorizontalAlignment="Left">
<RadioButton Content="{DynamicResource Locale}" Margin="10,0,0,0" x:Name="rd_LOCALE" VerticalAlignment="Center" IsChecked="{Binding Path=REMOTO, Converter={StaticResource InverseBooleanConverter}}" GroupName="Location" Panel.ZIndex="9" TabIndex="10" />
<RadioButton Content="{DynamicResource Remoto}" Margin="10,0,6,0" x:Name="rd_REMOTO" VerticalAlignment="Center" IsChecked="{Binding REMOTO}" GroupName="Location" Panel.ZIndex="10" TabIndex="11" Tag="PRISMA" />
</StackPanel>
WhenI change from one record to another, the converter gives me error... why? It fails the "if (targetType != typeof(bool))" row. So I tried to change that like:
if (value.getType() != typeof(bool))
but in this way, without fails nothing in the code, it put the wrong value in the radiobutton!
You need to make sure that the value converter is referenced in the XAML
<UserControl.Resources>
<myproject:InverseBooleanConverter x:Key="InverseBooleanConverter" />
</UserControl.Resources>
where my project is the namespace in which the value converter class is defined
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!
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>