I bound my text box to property (only text box) and used converter which just return opposite bool value.
XAML
<TextBox Height="23" HorizontalAlignment="Left" Margin="13,41,0,0" Text="{Binding Path=CurrentProfile.profileName}" IsEnabled="{Binding Path=CurrentProfile.isPredefined, Converter={StaticResource PredefinedToControlEnabled}}" VerticalAlignment="Top" Width="247" Grid.ColumnSpan="2" TabIndex="1" />
Converter
public class PredefinedToControlEnabled: IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var isPredefined = (bool)value;
return !isPredefined;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
When the property value isPredefined is true, the IsEnabled property of TextBox is set correctly to false. When the isPredefined is false, the converter returns false and all controls on GUI sets IsEnabled property to false, what means that application is not useable anymore (it works in background naturally). Why it is happening?
How does it look like:
Found,
VS automagically add line to Window properties
IsEnabled="{Binding Path=CurrentProfile.isPredefined}"
but the question still is, how?
Related
I'm trying to convert a string on a label (or anything) to another string. This is for Icon fonts.
Converter
[ValueConversion(typeof(string), typeof(string))]
public class StringToIconConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
string property = ((string)value).ToLower();
switch (property)
{
case "maximize": return #"\e901";
default return property;
}
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return DependencyProperty.UnsetValue;
}
...
}
Then I've added it to my pages that need it
<Helpers:StringToIconConverter x:Key="Icon" />
And this is how I'm setting it
<Button Style="{StaticResource NavButton}"
Tag="Document"
Command="{Binding GotoDataMatrixEnterCommand}">
<Button.Content>
<Label Content="{Binding Source={RelativeSource Self},
Path=Tag,
Converter={StaticResource Icon},
UpdateSourceTrigger=LostFocus}"
Tag="Document" />
</Button.Content>
</Button>
And what I'm getting is
Windows.System.Control.Label in its place. Am I not converting it properly, I'm not quite sure why it is not replacing the correct information. I've tried a few things, and reading up online though I'm stuck at the moment. Plus when I try to debug it doesn't work (it never hits the breakpoints)
The problem is with the Binding on Label.Content. You should use RelativeSource, not Source.
It should be:
RelativeSource={RelativeSource Mode=Self}
Also, you have a syntactic error in the switch statement of StringToIconConverter: default return property; should be default: return property; (you're missing a colon).
I have a property on my view model of type decimal?. NULL should be a valid value for this property, but when I erase the text from the DecimalUpDown control, a validation error occurs and the property is not given the value NULL (whatever it was previously remains).
The control is declared in xaml like:
<xctk:DecimalUpDown ValueChanged="UpDownBase_OnValueChanged" Text="{Binding ServiceSize}" Minimum="0" Grid.Column="4" Grid.Row="2" Margin="5" IsEnabled="{Binding IsEditable}"/>
It will bind correctly if I enter a number
But as soon as the number is erased a validation error occurs, and the value can't be set back to NULL (in this case the model still has "5" as the value for "ServiceSize").
Validation.GetHasError() returns true for this control. Can I remove the Validation Rules entirely somehow?
You can implement an IValueConverter to handle empty input.
public class DecimalUpDownValueConverter : IValueConverter
{
public object Convert(object value, Type targetType,
object parameter, CultureInfo culture)
{
// handle input on a case-to-case basis
if(value == null)
{
// Do something
return 0;
}
else
{
return value;
}
}
public object ConvertBack(object value, Type targetType,
object parameter, CultureInfo culture)
{
// Do the conversion from model property to DecimalUpDownValue
return value;
}
}
On your view: (Assuming you added the DecimalUpDownValueConverter as a static resource)
<xctk:DecimalUpDown ValueChanged="UpDownBase_OnValueChanged" Text="{Binding ServiceSize, Converter = { StaticResource DecimalUpDownValueConverter }}" Minimum="0" Grid.Column="4" Grid.Row="2" Margin="5" IsEnabled="{Binding IsEditable}"/>
I have a group of ribbon toggle buttons inside of the same container in my XAML like this:
<ribbon:RibbonGroup Header="Layouts">
<ribbon:RibbonToggleButton Label="One"
IsChecked="{Binding PaneManager.Layout,
Converter={StaticResource EnumToBooleanConverter},
ConverterParameter={s:Static windows:Layouts.One}}"/>
<ribbon:RibbonToggleButton Label="Two Vertical"
IsChecked="{Binding PaneManager.Layout,
Converter={StaticResource EnumToBooleanConverter},
ConverterParameter={s:Static windows:Layouts.TwoVertical}}"/>
<!-- etc. for 2 horizontal and 4 panes -->
</ribbon:RibbonGroup>
I'm using the same EnumToBooleanConverter outlined in this answer:
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;
}
}
The problem is that when a user clicks the toggle button that's already selected, the toggle button happily turns itself off--even though the bound value matches that toggle button. When tracing through the code, what happens is that the ConvertBack method is called and it returns Binding.DoNothing. Afterwards, Convert is not called to reassign the value. When ConvertBack returns a value (i.e. it is clicked a second time and IsChecked is true again), the Convert method is called to reassign the value.
If I change the return type on false to be DependencyObject.UnsetValue, the toggle button is still turned off but now it has a red outline.
How do I force WPF to re-evaluate the bound value so that the toggle button stays on?
OK, it seems I have to control whether the toggle button IsHitTestVisible to make it behave properly. If I change my toggle buttons to look like this:
<ribbon:RibbonGroup Header="Layouts">
<ribbon:RibbonToggleButton Label="One"
IsChecked="{Binding PaneManager.Layout,
Converter={StaticResource EnumToBooleanConverter},
ConverterParameter={s:Static windows:Layouts.One}}"
IsHitTestVisible="{Binding IsChecked,
RelativeSource={RelativeSource Self},
Converter={StaticResource InverseBooleanConverter}}"/>
<ribbon:RibbonToggleButton Label="Two Vertical"
IsChecked="{Binding PaneManager.Layout,
Converter={StaticResource EnumToBooleanConverter},
ConverterParameter={s:Static windows:Layouts.TwoVertical}}"
IsHitTestVisible="{Binding IsChecked,
RelativeSource={RelativeSource Self},
Converter={StaticResource InverseBooleanConverter}}"/>
<!-- etc. for 2 horizontal and 4 panes -->
</ribbon:RibbonGroup>
And then supply the following converter:
public class InverseBooleanConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return !(bool)value;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return !(bool)value;
}
}
It feels like a hack, but it does prevent toggling back off. I am seriously open to more elegant solutions.
I have put breakpoints inside the Value Converter and they are never triggered, but the page renders with no image being shown.
The XAML:
xmlns:datatypes="clr-namespace:DataTypes_Portable;assembly=DataTypes_WinPhone8"
...
<phone:PhoneApplicationPage.Resources>
<datatypes:WinPhone8ImageConverter x:Key="ImageConverter" />
</phone:PhoneApplicationPage.Resources>
...
<Image x:Name="LevelImage" HorizontalAlignment="Left" Height="Auto" VerticalAlignment="Top" Width="Auto" Margin="0" Grid.ColumnSpan="5" Source="{Binding Converter={StaticResource ImageConverter}, Path=App.Main.Game.CurrentLevel.CurrentPart.Image}"/>
The CS:
public class WinPhone8ImageConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var imageProvider = value as WinPhone8ImageProvider;
return imageProvider.Image;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
From what I can understand (by process of trial and elimination and looking at what exceptions are thrown) the problem is coming with part of the XAML where I am trying to bind to the value.
At a breakpoint the value at App.Main.Game.CurrentLevel.CurrentPart.Image is being set correctly (ie is an instance of WinPhone8ImageProvider).
It turns out this was nothing to do with the converter at all. The value was binding before the image had loaded (so the source was empty). For future reference check to make sure you are implementing theINotifyPropertyChanged correctly in your view models.
I have a WPF window with a Grid and a TreeView. The datacontext for the Grid is bound to the selected item on the treeview. However, because not all treeviewitems are applicable, I want to disable the grid if the treviewitem isn't applicable. So, I created a value converter to do a null check and return a bool. (Applicable items would not be null in this case)
The problem is that the value converter is never used. I set break points and they are never hit. I have other value converters I'm using and they all work just fine.
Is there something I'm missing?
<Grid Grid.Column="1" Grid.Row="0" DataContext="{Binding MyVal}" IsEnabled="{Binding MyVal, Converter={StaticResource NullCheckConverter}}" Margin="2,2,2,2">
Not that it's important for this question but here is the ValueConverter code:
internal class NullCheckValueConverter : IValueConverter
{
#region IValueConverter Members
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return !(value == null);
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
#endregion
}
That's because you bind DataContext to the same value as you binding IsEnabled. So for IsEnabled it actually looking for MyVal.MyVal. Replace to:
IsEnabled="{Binding Converter={StaticResource NullCheckConverter}}"
Also further if you have issues with binding, check in debug mode output window for binding errors.