GoodDay!
I'm not good with wpf and binding, i need your help. I have already bind a Json Object (JObject) to a Column of TextBox.
<TextBox Width="250" Text="{Binding Path=Property, Converter={StaticResource jPropertyConverter}, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
I can show properly the data of the Jobject when i start my wpf window, now i need to ConvertBack the data modified when i modify one of the textbox of the columns, from that TextBox to the JObject, and the related JValue.
public class JPropertyConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (value is JProperty)
{
JToken valoreProperty = (value as JProperty).Value;
if ((valoreProperty is JValue))
return (valoreProperty as JValue).Value;
}
return DependencyProperty.UnsetValue;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
??
}
}
I can change the Value of the "leaves" of this JObject tree like:
(valoreProperty as JValue).Value = "Hello!";
How can i change the "leaves" of this JObject tree in the convert back?
Sorry for my english.
Thanks and bye
EDIT:
Thanks dbc! It works, many thanks!
Now i need to show in another column, every lenght of the value inside of the textbox, obviously if i change the value in the texbox the relative lenght value will change too.
I tried:
<DataGridTextColumn Header="Lunghezza2" IsReadOnly="True" Width="50" Binding="{Binding Path=Property.Value.Value.toString().Length, UpdateSourceTrigger=PropertyChanged, Mode=OneWay}" />
or in another way with a converter, passing a JProperty
public class LengthConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (value is JProperty)
{
JToken jValue = (value as JProperty).Value;
if ((jValue is JValue) && (jValue as JValue).Value != null)
return (jValue as JValue).Value.ToString().Length.ToString();
else
return "0";
}
else
return "";
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
But every try didn't works when i change the textbox value, any tips?
Many thanks again!
You don't need a converter for this purpose. Assuming your Property property returns a JProperty, you can bind directly to JProperty.Value.Value
<TextBox Name="PropertyTextBox"
Text="{Binding Path=Property.Value.Value, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
/>
If you want to disable the TextBox if the bound Property is not a "simple" JProperty (one with just a JValue for its value), you can do:
<TextBox Name="PropertyTextBox"
Text="{Binding Path=Property.Value.Value, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
IsEnabled="{Binding Path=Property, Converter={StaticResource IsSimpleJPropertyConverter}, Mode=OneWay}"
/>
Using the converter
public class IsSimpleJPropertyConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (value is JProperty)
{
JToken jValue = (value as JProperty).Value;
if (jValue is JValue)
return true;
}
return false;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
Related
Can i simply add characters without binding this characters to my ViewModel?
I need these to show physical units like cm, mm, m, cm^3, ...
XAML:
<TextBox
Text="{Binding value_top}" //sth. like + "cm"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Width="50"/>
VW:
value_top = 22.9
Output aim:
22.9 cm
I know, I can overlay a Label, but i would like to know if there is another possibility.
Create a converter which will take the double and return a string. Here is an untested example to get you started:
public class DoubleToString: IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var dbl = (double) value;
return $"{dbl} cm";
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return Double.Parse(Regex.Match(value.ToString(), "[\d.]+").Value);
}
}
I have a propery PhoneNumber and in the UI, I have 2 textboxes, one is the prefix, and the other one is the postfix, how can I bind it to the property? (The property inside the DataContext).
<TextBox Grid.Column="0" MaxLength="3" /> //Prefix
<TextBlock Grid.Column="1" Text="-" />
<TextBox Grid.Column="2" /> //Postfix
The only way I see it work is with code behind using textbox1.Text + textbox2.Text... Is there a better way?
Thanks in advance :)
Just use two more properties in the data context
code is not complied or tested
public string PhoneNumber { get; set; }
public string Prefix
{
get
{
return PhoneNumber.Substring(0, 3);
}
set
{
// replace the first three chars of PhoneNumber
PhoneNumber = value + PhoneNumber.Substring(3);
}
}
public string Postfix
{
get
{
return PhoneNumber.Substring(3);
}
set
{
// replace the chars of starting from index 3 of PhoneNumber
PhoneNumber = PhoneNumber.Substring(0, 3) + value;
}
}
I think uou can use Converter for this purpose, the example going one way can look like this:
In this my Number is a string 000-000000, but you can surely change it.
In XAML:
<Window.Resources>
<conv:PostixConverter x:Key="PostfixConv" xmlns:conv="clr-namespace:Example.Converters"/>
<conv:PrefixConverter x:Key="PrefixConv" xmlns:conv="clr-namespace:Example.Converters"/>
</Window.Resources>
<StackPanel>
<TextBox MaxLength="3" Text="{Binding Number, Converter={StaticResource PrefixConv}}"/>
<TextBlock Text="-" />
<TextBox Text="{Binding Number, Converter={StaticResource PostfixConv}}"/>
</StackPanel>
And in code behind:
namespace Example.Converters
{
public class PrefixConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (value == null) return null;
else return ((string)value).Substring(0, 3);
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
public class PostixConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (value == null) return null;
else return ((string)value).Substring(4);
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
}
I have XML file and listView and I want to hide specific XAML element in this list View Item if value of XML element <Finished> equals false.
How can I do it?
You bind the XAML element's visibility to the Finished property of the list item.
You will need to bind it through a converter that takes a boolean value and returns Visibility.Visible or Visibility.Collapsed as appropriate:
<TextBlock Visibility="{Binding Finished,
Converter={StaticResource BoolToVisibilityConverter}}"/>
The converter:
public class GenderConverter: IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value is bool)
return (bool)value ? Visibility.Visible : Visibility.Collapsed;
else
return Visibility.Collapsed;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw NotImplementedException();
}
}
If the value isn't a boolean the converter will be slightly more complex and you may need to pass in a ConverterParameter as a control value so you can have more control over when you return Visibility.Visible
I'm adding items to a menuitem through the itemsSource property. (element name is videoCapDevices)
ItemsSource="{Binding Source={x:Static Devices}}"
And now i want to respond to the selected menuitem , may be to show a videostream with the selected camera devices
VideoCaptureDevice="{Binding Path=SelectedItem, ElementName=videoCapDevices}"
But this just works for comboboxes or listboxes.
How can i change the "path selector" to reach the selected menuitem.
Thank you
try to cast using a converter
public class DeviceConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if(value==null)
return null;
return ((Device)value).CaptureDeviceName;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return value;
}
}
and
VideoCaptureDevice="{Binding Converter=DeviceConverter ,Path=SelectedItem, ElementName=videoCapDevices}"
Unknown attribute Foreground on
element TextBlock
I have this error, when I'm trying to
change the Foreground color depending
on "Read_State"
public class ReadConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
bool ReadState =(bool)parameter;
if (ReadState == false)
return new SolidColorBrush(Colors.Black);// new SolidColorBrush((Color)Application.Current.Resources["PhoneAccentColor"]);
else
return new SolidColorBrush(Colors.Black);
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
In Xaml
<TextBlock Foreground="{Binding Converter={StaticResource ReadConverter},ConverterParameter={Binding Read_State}}" Text="{Binding Path=TexT}" Style="{StaticResource PhoneTextNormalStyle}" TextWrapping="Wrap"/>
The error may just be a bit misleading. You can't use Binding on the ConverterParameter.
You are miss using the converter, you don't need the ConverterParameter at all. Your converter code ought to look like this:-
public class ReadConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
bool ReadState =(bool)value;
if (ReadState == false)
return new SolidColorBrush(Colors.Black);// new SolidColorBrush((Color)Application.Current.Resources["PhoneAccentColor"]);
else
return new SolidColorBrush(Colors.Black);
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
and your Xaml:-
<TextBlock Foreground="{Binding Read_State, Converter={StaticResource ReadConverter}}" Text="{Binding Path=TexT}" Style="{StaticResource PhoneTextNormalStyle}" TextWrapping="Wrap"/>
You might also want to have a read of this blog for future use.