Make default visibility collapsed when there is no binding element - wpf

I have a user control with textbox and button which are bound to properties from viewmodel.
<Grid>
<StackPanel>
<TextBox Text=" Hi" IsEnabled="{Binding IsReadOnly, UpdateSourceTrigger=PropertyChanged}"></TextBox>
<Button Content="B" Visibility="{Binding IsVisible, UpdateSourceTrigger=PropertyChanged, Converter={StaticResource BooleanToVisibilityConverter}}"></Button>
</StackPanel>
</Grid>
How to make the button invisible when the datacontext is not provided for this usercontrol?

FallbackValue
<Button Content="B" Visibility="{Binding IsVisible,
UpdateSourceTrigger=PropertyChanged,
Converter={StaticResource BooleanToVisibilityConverter}},
FallbackValue=Collapsed"></Button>

Related

ListBoxEditItem Visibility not working as expected

I have the following xaml and I am trying to set the ListBoxEditItem for Content="3" without using the ElementName for ck because I want to set the Visibility directly and not have the CheckBox. Why does the Visibility work for Content="2" ListBoxEditItem and not Content="3"? How do I set the Visibility directly?
<StackPanel>
<dxe:ComboBoxEdit EditValue="{Binding test, UpdateSourceTrigger=PropertyChanged}">
<Visibility>Visible</Visibility>
<Visibility>Collapsed</Visibility>
<Visibility>Hidden</Visibility>
</dxe:ComboBoxEdit>
<dxe:ListBoxEdit StyleSettings="{dxe:RadioListBoxEditStyleSettings}">
<dxe:ListBoxEditItem Content="1" />
<dxe:ListBoxEditItem Content="2" Visibility="{Binding Visibility, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, ElementName=ck}" />
<dxe:ListBoxEditItem Content="3" Visibility="{Binding test, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
</dxe:ListBoxEdit>
<CheckBox x:Name="ck" Visibility="{Binding test, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
<TextBlock Text="some stuff" Visibility="{Binding Visibility, ElementName=ck}" />
</StackPanel>
I needed DataContext in the binding like so:
<dxe:ListBoxEditItem Content="3" Visibility="{Binding DataContext.test, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>

Binding to the Title of a Window does not always work

I need to databind two TextBlocks to the Window.Title property. The first one works via:
RelativeSource FindAncestor, AncestorType=Window}"
But the second one does not (it's deeply nested within a button ToolTip).
How can I change the second one to make it also display the Title of the Window?
<Window ...>
<Border ...>
<Grid ...>
<Grid ...>
<!-- TEXTBLOCK BELOW WORKS -->
<TextBlock Grid.Column="2" Text="{Binding Title, RelativeSource={RelativeSource FindAncestor, AncestorType=Window}}"
HorizontalAlignment="Stretch" VerticalAlignment="Center" Foreground="White" FontSize="18px" FontStretch="UltraExpanded" />
<Button Grid.Column="3" HorizontalAlignment="Right" VerticalAlignment="Stretch"
Background="Transparent" BorderBrush="Transparent" Foreground="Transparent"
ToolTipService.InitialShowDelay="0" ToolTipService.BetweenShowDelay="0" ToolTipService.ShowDuration="60000">
<Button.ToolTip>
<ToolTip x:Name="helpButtonTooltip" Width="240" ToolTipService.InitialShowDelay="0">
<!-- TEXTBLOCK BELOW DOES NOT WORK; HOW CAN I MAKE IT WORK? -->
<TextBlock Text="{Binding Title, RelativeSource={RelativeSource FindAncestor, AncestorType=Window}}"
HorizontalAlignment="Stretch" VerticalAlignment="Center" Foreground="White" FontSize="18px" FontStretch="UltraExpanded" />
The tool tip is displayed in a popup and is not part of the same visual tree as the button or your window. Consequently, RelativeSource and ElementName bindings do not work.
What you can do is bind the window title to the Tag property of your button and then bind the Text of the tool tip TextBlock to the Tag property of the PlacementTarget (which is the button).
<Button Tag="{Binding Title, RelativeSource={RelativeSource FindAncestor, AncestorType=Window}}">
<Button.ToolTip>
<ToolTip>
<TextBlock Text="{Binding PlacementTarget.Tag, RelativeSource={RelativeSource AncestorType={x:Type ToolTip}}}"/>
</ToolTip>
</Button.ToolTip>
</Button>

How to bind to property of sibling control?

In a listbox of items, one item can be designated as the primary item. In the template, I have a button bound to a parameterized command (the specific item in the collection is the parameter passed to the command in the datacontext) that is visible only if the item is not currently the primary item. If the item IS the primary item, I want to display a static image. Since I can't bind the image to the command to witch I am binding the button, I figured I could bind the Visibility property of the image to the "inverse" of the Visibility property of the button. (i.e. when the button is visible, the image is hidden and vice versa.) But I can't figure out how to do this. The button is a sibling of the image within a grid within the template. Here's my template...
<DataTemplate>
<StackPanel Orientation="Vertical">
<Grid>
<Grid.ColumnDefinitions>
...
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="{Binding Path=FormattedNumber}" Style="{StaticResource FieldDataTextBlock}" FontWeight="Bold" />
<!-- How can I make this image aware of the following button's state? -->
<Image Grid.Column="2" Source="/Resources/Star.Pressed.png" Visibility="{Binding RelativeSource={RelativeSource AncestorType=Grid}, Path={}}" Width="20" Height="20" />
<Button Grid.Column="2" x:Name="btnMakePrimary" Style="{StaticResource StarButton}" Command="{Binding ElementName=lstPhoneNumbers, Path=DataContext.MakePrimaryPhoneNumberCommand}" CommandParameter="{Binding}" ToolTip="Set as display number." Visibility="{Binding Path=IsEnabled, RelativeSource={RelativeSource Self}, Converter={StaticResource BoolVisibility}}" />
<Button Grid.Column="4" Style="{StaticResource DetailsButton}" Command="{Binding ElementName=lstPhoneNumbers, Path=DataContext.ViewPhoneNumberCommand}" CommandParameter="{Binding}" />
<Button Grid.Column="6" Style="{StaticResource DeleteButton}" Command="{Binding ElementName=lstPhoneNumbers, Path=DataContext.DeletePhoneNumberCommand}" CommandParameter="{Binding}" />
</Grid>
<Grid >
<Grid.ColumnDefinitions>
...
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="{Binding Path=PhoneTypeString}" Style="{StaticResource FieldDataTextBlock}" />
<TextBlock Grid.Column="2" Text="(notes)" Foreground="Blue" ToolTip="{Binding Path=PhoneNumberNote}" Visibility="{Binding Path=HasNote, Converter={StaticResource BoolVisibility}}" />
</Grid>
</StackPanel>
</DataTemplate>
Either that, or is there a way to bind the image to a method in the parent datacontext that takes a parameter?
Thanks.
J
Never mind... I was able to make it happen via the ElementName attribute of the binding and fixing an issue with the included image resource which was messing with my visuals:
<Button Grid.Column="2" Name="btnMakePrimary" Style="{StaticResource StarButton}" Command="{Binding ElementName=lstPhoneNumbers, Path=DataContext.MakePrimaryPhoneNumberCommand}" CommandParameter="{Binding}" ToolTip="Set as display number." Visibility="{Binding Path=IsEnabled, RelativeSource={RelativeSource Self}, Converter={StaticResource BoolVisibility}}" />
<Image Grid.Column="2" Source="/Resources/Star.Pressed.png" Visibility="{Binding ElementName=btnMakePrimary, Path=IsEnabled, Converter={StaticResource BoolVisibilityReverse}}" Width="20" Height="20" />

Make the content of a checkbox listview item clickable to activate the checkbox

I'm populating a listview with checkbox listview items. Currently the only way to check the box is by clicking on just the box. How can I extend this to make the content of the listview item activate the checkbox also
<CheckBox VerticalAlignment="Stretch" HorizontalAlignment="Stretch" HorizontalContentAlignment="Stretch" Margin="2"
IsChecked="{Binding IsSelected, Mode=TwoWay}" Content="{Binding Value}" ContentTemplate="{Binding FilterValueTemplate, ElementName=Q_ROOT}"/>
Above was in my theming, below is the actual view.
<StackPanel Orientation="Horizontal">
<CheckBox VerticalAlignment="Center" Margin="2" IsChecked="{Binding IsChecked, Mode=TwoWay, RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=ListViewItem}}">
<CheckBox.Content>
<ContentPresenter VerticalAlignment="Center" Content="{Binding Value}" ContentTemplate="{Binding FilterValueTemplate, ElementName=QFSP_ROOT}"/>
</CheckBox.Content>
</CheckBox>
</StackPanel>
Bind IsChecked with IsSelected property of ListViewItem using RelativeSource :
<CheckBox IsChecked="{Binding IsSelected, RelativeSource={RelativeSource
Mode=FindAncestor, AncestorType=ListViewItem}}"/>
I moved the content presenter content inside the checkbox itself and it now works fine:
<CheckBox VerticalAlignment="Center" Margin="2" IsChecked="{Binding IsSelected, Mode=TwoWay}"
Content="{Binding Value}" ContentTemplate="{Binding FilterValueTemplate, ElementName=QFSP_ROOT}"/>

How to access checkbox control inside TabItem from TabItem HeaderTemplate

I have tabItem which contains one CheckBox.Tab inside I am binding one ListBox. based on check box checked status I need to control visibility of ListBox. I binded IsChecked property to Visiblity property of ListBox by using Boolean to Visibility converter.But It is not changing the status of Listbox.
How do I get the control status?
Here I attached my code.
<TabItem Header="Trigger">
<TabItem.HeaderTemplate>
<DataTemplate>
<DockPanel>
<CheckBox x:Name="ui_chbTrigger" IsChecked="{Binding SelectedUiSeries.UiTriggerParameters.HasEcgPulsingConfig, Mode=TwoWay}"/>
<Label Content="Trigger" HorizontalAlignment="Center" FontSize="18" FontWeight="Bold"/>
</DockPanel>
</DataTemplate>
</TabItem.HeaderTemplate>
<Grid >
<ListBox Grid.Row="1" Style="{StaticResource S_ListBoxParameterScan}"
ItemContainerStyle="{StaticResource S_ListBoxItemScanParameter}"
Visibility="{Binding Path=IsChecked, Converter={StaticResource BooleanToVisiblityConverter}, ElementName=ui_chbTrigger}">
<ListBoxItem>
<util:HeaderComboBox Style="{DynamicResource S_HeaderComboBoxParameter}" Header="Trigger Type"
ItemsSource="{helpers:EnumBindingHelper {x:Type commonDefs:TriggerType}}"
SelectedItem="{Binding SelectedUiSeries.UiTriggerParameters.TriggerType,Mode=TwoWay}"/>
</ListBoxItem>
</ListBox>
</Grid >
</TabItem>
How can you reference control from TEMPLATE(your checkbox is in HeaderTemplate)
You can change your code as below
<TabControl>
<TabItem>
<TabItem.Header>
<DockPanel>
<CheckBox x:Name="ui_chbTrigger"/>
</DockPanel>
</TabItem.Header>
<Grid >
<ListBox Visibility="{Binding Path=IsChecked, Converter={StaticResource BooleanToVisiblityConverter}, ElementName=ui_chbTrigger}">
<ListBoxItem>
<TextBlock>1</TextBlock>
</ListBoxItem>
<ListBoxItem>
<TextBlock>2</TextBlock>
</ListBoxItem>
</ListBox>
</Grid >
</TabItem>
</TabControl>
Feel free to do the further changes as you need.
Your CheckBox is already bound to SelectedUiSeries.UiTriggerParameters.HasEcgPulsingConfig.
Instead of trying to do ElementName-based Binding, simply bind the other UI element to the same property in the ViewModel:
<ListBox Visibility="{Binding Path=SelectedUiSeries.UiTriggerParameters.HasEcgPulsingConfig,
Converter={StaticResource BooleanToVisiblityConverter}}"/>

Resources