Button still visible even if path sets to false - c#

<Button
VerticalAlignment="Stretch"
ToolTip="Convert selected Node(s)"
ToolTipService.ShowOnDisabled="False"
Visibility="{Binding Source={StaticResource serviceLocator}, Path=NetworkManager.NetworkViewModel.IsGenericProfileLoaded}"
Command="{Binding Path=ConvertToNonControlPlaneCommand}" >
<Image
Style="{StaticResource toolbarImageStyle}"
Source="/Resources/Icons/equipment_edit.png"
/>
</Button>
The button should be collapsed or invisible depending on the Path property called IsGenericProfileLoaded. Even if IsGenericProfileLoaded is false, the button is still visible. How to make it invisible. From other question on stackoverflow, it seems that i need to visibilitytoBoolean converter or is there anything that I can use here like disable="true"?

In general when a data binding does not work, debug the app in Visual Studio and look in the debug output. You can show the debug output by: menu / DEBUG / Windows / Output. Go in the application to that page and keep an eye to the messages shown in the debug output window. You will get some information about what does not work.
You are correct, in your case you need a converter. The data binding alone will not be able to assign a bool to a dependency property of type Visibility.
Here is a very simple version of such convertor:
public class BoolToVisibilityConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
bool booleanValue = (value as bool?).GetValueOrDefault();
return booleanValue ? Visibility.Visible : Visibility.Collapsed;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotSupportedException();
}
}
You will have to also add somewhere in XAML a static reference that makes this convertor available. Maybe in App.xaml something like this:
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:converters="clr-namespace:<replace_with_your_namespace>;assembly=<replace_with_your_assembly>">
...
<converters:BoolToVisibilityConverter x:Key="BoolToVisibilityConverter" />
...
</ResourceDictionary>
In your case the visibility will have to be set like this:
Visibility="{Binding Source={StaticResource serviceLocator}, Path=NetworkManager.NetworkViewModel.IsGenericProfileLoaded, Converter={StaticResource BoolToVisibilityConverter}}"
You will soon see that you need more flexibility from the convertor. You will want to convert a true to Visibility.Collapsed and a false to Visibility.Visible. Here is how such a more flexible convertor would be used in XAML:
Visibility="{Binding IsLocked, Converter={StaticResource BoolToVisibilityConverter}, ConverterParameter=not}"
And here is how the convertor method would have to be rewritten:
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
bool booleanValue = (value as bool?).GetValueOrDefault();
if (parameter != null)
{
if (parameter.ToString().Equals("not", StringComparison.OrdinalIgnoreCase))
{
booleanValue = !booleanValue;
}
else
{
throw new ArgumentException(string.Format(CultureInfo.InvariantCulture, "Invalid value for the BoolToVisibilityConverter parameter: '{0}'. The only valid values are null or 'not' (case insensitive)", parameter));
}
}
return booleanValue ? Visibility.Visible : Visibility.Collapsed;
}

Related

Inverted bool to radio button from dataContext to userControl

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

How can we handle Null Values while Binding data to Text block in Windows phone

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>

Boolean Converter not hitting converter

I'm using a boolean converter in my XAML in a WPF project. I want to disable a few buttons while "IsBusy" is true. I am absolutely sure that IsBusy is being set to true/false properly. I am able to successfully bind directly to IsBusy without the converter. The following does not currently work. I've put breakpoints in the actual converter class and the "Convert" and "ConvertBack" methods are never hit. What is wrong here?
IsEnabled="{Binding IsBusy, Converter={StaticResource InvertedBooleanConverter}}"
Resources:
<Window.Resources>
<converters:InvertedBooleanConverter x:Key="InvertedBooleanConverter" />
</Window.Resources>
Converters:
xmlns:converters="clr-namespace:MyProject.Converters"
The converter:
namespace MyProject.Converters
{
[ValueConversion(typeof(bool), typeof(bool))]
public class InvertedBooleanConverter : IValueConverter
{
#region IValueConverter Members
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();
}
#endregion
}
}
If isBusy dependancy property? if not the change form IsBusy will not be transmitted into isEnable
Take a step back and check that the binding is in the right place -- add <TextBlock Text="{Binding}" /> and make sure it shows the correct class (the one that contains IsBusy).

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;
}
}

Show WPF tooltip on disabled item only

Just wondering if it is possible to show a WPF on a disabled item ONLY (and not when the item is enabled).
I would like to give the user a tooltip explaining why an item is currently disabled.
I have an IValueConverter to invert the boolean IsEnabled property binding. But it doesn't seem to work in this situation. The ToolTip is show both when the item is enabled and disabled.
So is is possible to bind a ToolTip.IsEnabled property exclusively to an item's own !IsEnabled?
Pretty straightforward question I guess, but code example here anyway:
public class BoolToOppositeBoolConverter : IValueConverter
{
#region IValueConverter Members
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)
{
if (targetType != typeof(bool))
throw new InvalidOperationException("The target must be a boolean");
return !(bool)value;
}
#endregion
}
And the binding:
<TabItem Header="Tab 2" Name="tabItem2" ToolTip="Not enabled in this situation." ToolTipService.ShowOnDisabled="True" ToolTipService.IsEnabled="{Binding Path=IsEnabled, ElementName=tabItem2, Converter={StaticResource oppositeConverter}}">
<Label Content="Item content goes here" />
</TabItem>
Thanks folks.
JustABill's suggestion worked. I also needed to define the string as a resource to avoid problems with quotation marks. And you still need to set ToolTipService.ShowOnDisabled="True".
So, here is the working code which shows how to display a tooltip in WPF only when an item is disabled.
In the top container, include the system namespace (see sys below). I also have a Resources namespace, which I called "Res".
<Window x:Class="MyProjectName.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
xmlns:Res="clr-namespace:MyProjectName.Resources"
>
Then you need
<Window.Resources>
<Res:FalseToStringConverter x:Key="falseToStringConv" />
<sys:String x:Key="stringToShowInTooltip">This item is disabled because...</sys:String>
</Window.Resources>
In my case, it was a tab item that I was interested in. It could be any UI element though...
<TabItem Name="tabItem2" ToolTipService.ShowOnDisabled="True" ToolTip="{Binding Path=IsEnabled, ElementName=tabItem2, Converter={StaticResource falseToStringConv}, ConverterParameter={StaticResource stringToShowInTooltip}}">
<Label Content="A label in the tab" />
</TabItem>
And the converter in code behind (or wherever you want to put it). Note, mine went into the a namespace called Resources, which was declared earlier.
public class FalseToStringConverter : IValueConverter
{
#region IValueConverter Members
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (value is bool && parameter is string)
{
if ((bool)value == false)
return parameter.ToString();
else return null;
}
else
throw new InvalidOperationException("The value must be a boolean and parameter must be a string");
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
#endregion
}
A little out of date, but I got this working by setting RelativeSource mode to Self instead of setting the ElementName within the Binding.
<TabItem Header="Tab 2" Name="tabItem2" ToolTip="Not enabled in this situation." ToolTipService.ShowOnDisabled="True" ToolTipService.IsEnabled="{Binding Path=IsEnabled, RelativeSource={RelativeSource Mode=Self}, Converter={StaticResource oppositeConverter}}">
<Label Content="Item content goes here" />
</TabItem>

Categories