Binding to another element? - c#

I can't get this to work, I have a TextBlock that I want to bind its 'Text' property to a the Window's title.
I tried this:
<TextBlock Text="{Binding path=Window.Title}" ... />

You're using the wrong syntax with binding. First add a name to your Window, let it be "window1".
Then do the following:
<TextBlock Text"{Binding ElementName=window1, Path=Title}" ... />

<TextBlock Text="{Binding Path=Title, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Window}}}" />
If the Window element has no name, you can refer to it with a RelativeSource.

Related

Error Using RelativeSource FindAncestor in WPF

I do have an Window (DataContext VM) and a Listview (ItemSource Observable List in VM)
Data comes from an sqlite DB, the Observable List is Type of Model, representing Residents.
Each Resident should have an "CheckIn" or "CheckOut" Button, for them, i do have ICommands in my VM.
<ListView ItemsSource="{Binding Oc_BewohnerList}">
<ListView.ItemTemplate>
<DataTemplate>
<WrapPanel>
<TextBlock Text="Name:" Width="50"/>
<TextBlock Text="{Binding Nachname, StringFormat={}{0}\, }" FontWeight="Bold"/>
<Button Content="Check In" Command="{Binding Source={RelativeSource AncestorType={x:Type viewModels:BewohnerVM}}, Path=CheckInCommand}" CommandParameter="{Binding Id}" />
Why do i get an Error "Die Eigenschaft "CheckInCommand" wurde im Objekt vom Typ "RelativeSource" nicht gefunden." That the CheckInCommand is not found?
I did it first with Xamarin.Forms and there it worked in a similiar way ... i cant find a solution myself, tried tons of combinations for realtivesource and ancestorlevel ...
Thx in advance
Nala
A relativesource binding is up the visual tree.
As in controls not viewmodels.
You're not going to be looking for a viewmodel.
If the command is a property on VM and that's the datacontext of the window then the ListView inherits that datacontext.
You've not explained everything but I think you need more like:
<Button Content="Check In"
Command="{Binding RelativeSource={RelativeSource AncestorType={x:Type ListView}},
Path=DataContext.CheckInCommand}"
CommandParameter="{Binding Id}" />
Likely just a small syntax error and you want (note the double usage of RelativeSource , once as a property of Binding once as MarkupExtension...)
EDIT and also the AncestorType should be an UIElement, whose DataContext exposes that CheckInCommand.
<Button Content="Check In"
Command="{Binding RelativeSource={RelativeSource AncestorType={x:Type ListView}}, Path=DataContext.(viewModels:BewohnerVM.CheckInCommand)}"
CommandParameter="{Binding Id}" />

Binding by relative source is not working in Tooltip WPF

I am using Syncfusion visual style. I am trying to bind the ToolTip foreground inside the TextBlock present inside the StackPanel for displaying the ToolTip text.But the binding doesn't work properly in the TextBlock.
MainWindow.xaml
<Grid>
<CheckBox Grid.Row="5" Grid.Column="1" HorizontalAlignment="Center" Margin="0,4,10,0" VerticalAlignment="Center" IsChecked="{Binding AutoAdd, Mode=TwoWay}">
<CheckBox.ToolTip>
<StackPanel>
<TextBlock Foreground="{Binding Path=Foreground, Mode=OneWay, RelativeSource={RelativeSource AncestorType={x:Type ToolTip}}}" FontWeight="Bold" FontSize="14" Margin="0,0,0,5">Automatically Add To Path</TextBlock>
<TextBlock Foreground="{Binding Path=Foreground, Mode=OneWay, RelativeSource={RelativeSource AncestorType={x:Type ToolTip}}}">
If this path is associated with the primary configuration,
<LineBreak />
automatically add newly instantiated optical elements to the end of the path.
</TextBlock>
<Border BorderBrush="Silver" BorderThickness="0,1,0,0" Margin="0,8" />
<WrapPanel>
<Image Margin="0,0,5,0" />
<TextBlock Foreground="{Binding Path=Foreground, Mode=OneWay, RelativeSource={RelativeSource AncestorType={x:Type ToolTip}}}" FontStyle="Italic">Press F1 for more help</TextBlock>
</WrapPanel>
</StackPanel>
</CheckBox.ToolTip>
</CheckBox>
</Grid>
Any other work around regarding this issue.
Regards,
Hari Prasad
A Tooltip is in a different datacontext and not directly in the visual tree to a control which appears to be it's parent. Hence, when you search up the visual tree using relativesouce, it will find nothing.
You may use PlacementTarget to reference the thing which is nominally it's parent - checkbox in your markup
"{Binding Path=PlacementTarget.PropertyName, RelativeSource={RelativeSource Self}}"
Here PropertyName is whichever property you want.
That could be DataContext.ViewModelProperty if you wanted a property in your viewmodel.
In this instance I would try
Foreground="{Binding Path=PlacementTarget.Foreground, RelativeSource={RelativeSource Self}}"
Depending on your usage, maybe using a dynamicresource would be simpler though.

CaliburnMicro Binding View inside RadGridView.RowDetailsTemplate

I have a RadGridView with a GridViewToggleRowDetailsColumn, which can expand a selected item and show more Details. I want to use CaliburnMicro to Display the DetailsView, so I add a property of the DetailsViewModel to my "MainViewModel" and add a ContentControl with a Binding to it.
<telerik:RadGridView ItemsSource="{Binding Products.View}"
SelectedItem="{Binding SelectedProduct}" ... >
<telerik:RadGridView.RowDetailsTemplate>
<DataTemplate>
<ContentControl cal:View.Model="{Binding ProductDetailsViewModel}" />
</DataTemplate>
</telerik:RadGridView.RowDetailsTemplate>
<telerik:RadGridView.Columns>
<telerik:GridViewToggleRowDetailsColumn />
...Columndefinitions...
<telerik:RadGridView.Columns>
</telerik:RadGridView>
The problem is, that the Details are not displayed. From here I read that the binding fails because of the ItemsSource. So i tried
<ContentControl cal:View.Model="{Binding ProductDetailsViewModel, RelativeSource={RelativeSource FindAncestor, AncestorType=UserControl}}" />
but it still does not work.
If the ProductDetailsViewModel property is the defined in the same class as the Products property that the RadGridView is bound to, try this:
<ContentControl cal:View.Model="{Binding DataContext.ProductDetailsViewModel, RelativeSource={RelativeSource FindAncestor, AncestorType=telerik:RadGridView}}" />

WPF Binding two dependency properties of the same control but two datacontexts needed

I have two controls in a grid.
<TextBlock Text="{Binding Name}" TextAlignment="Center" />
<TextBox Visibility="{Binding ElementName=EditMode,Source={Binding RelativeSource=
{RelativeSource FindAncestor, AncestorType={x:Type Window}}},
Converter={StaticResource BoolToVis}}" Text="{Binding Name}"
TextAlignment="Center" />
I am trying to implement something like an editable/non editable behaviour. I know i might choose for a TextBox and simply change the IsEditable property but still, in my scenarion i would need to DataContext, at least that's what i am thinking of.
In my example, the TextBlock works fine, and the Text property on the TextBox also works fine but for the Visibility part, i want to bind to a data property ( EditMode which is a boolean) found on some other layer. Is there a way to change the DataContext to that, but only for the Visibility ? The Text property should remain as it is now.
Should i try a hack, to define an invisible checkbox, change IsChecked when my Edit button is clicked and bind directly to that ? I will try this. I think this way, no DataContext changing is needed.
#FrumRoll is correct that you can access a property that is not in the set DataContext object using a RelativeSource Binding. However, I'm not sure that their code is quite right... try this:
<TextBox Visibility="{Binding DataContext.EditMode, RelativeSource={RelativeSource
AncestorType={x:Type YourXamlPrefix:MainWindow}}}, Converter={StaticResource
BoolToVis}}" Text="{Binding Name}" TextAlignment="Center" />
Clearly, you'll need to change the YourXamlPrefix value with your local XAML Namespace Prefix and MainWindow with the name/type of your Window if it is not called MainWindow. This also assumes that your EditMode property has been defined in that Window.
This may also work, but is not specifically looking for your exact Window, so may have some problems:
<TextBox Visibility="{Binding DataContext.EditMode, RelativeSource={RelativeSource
AncestorType={x:Type Window}}}, Converter={StaticResource BoolToVis}}"
Text="{Binding Name}" TextAlignment="Center" />
It seems to me you were almost there, you should be able to use a RelativeSource to do this. The issue is that you misused ElementName, ElementName is to bind to a property of a named source and would be used instead of RelativeSource. What you meant to use was Path, which is optional as seen below.
<TextBox Visibility="{Binding DataContext.EditMode, RelativeSource={RelativeSource AncestorType={x:Type Window}},
Converter={StaticResource BoolToVis}}"
Text="{Binding Name}" TextAlignment="Center" />

WPF - How to display a tooltip on a hyperlink only when the hyperlink is disabled

This is a more specific description of my problem from a previous question, with a follow-up answer.
I had a standard hyperlink defined in XAML:
<TextBlock>
<Hyperlink IsEnabled="{Binding LinkEnabled}">
<TextBlock Text="{Binding Text}"/>
</Hyperlink>
</TextBlock>
The hyperlink's IsEnabled property is bound to a property on the view model, the value of which can change. I needed to place a tooltip on the hyperlink which would only be displayed if the hyperlink is disabled.
To show the tooltip only when the hyperlink is disabled, the ToolTipService.ShowOnDisabled and ToolTipService.IsEnabled (with the negation converter) properties must be set on the hyperlink:
<TextBlock>
<Hyperlink IsEnabled="{Binding LinkEnabled}"
ToolTip="ToolTip"
ToolTipService.ShowOnDisabled="True"
ToolTipService.IsEnabled="{Binding IsEnabled, RelativeSource={RelativeSource Self}, Converter={StaticResource negateConverter}}">
<TextBlock Text="{Binding Text}"/>
</Hyperlink>
</TextBlock>
However, the tooltip won't be shown, since once the hyperlink is disabled, it stops being hit-testable, because it is contained in the TextBlock (or so I understood).
Thus, the solution would be to change the "IsEnabled" property on the parent TextBlock, not on the hyperlink.
However, this works:
<TextBlock IsEnabled="False">
But this doesn't:
<TextBlock IsEnabled="{Binding LinkEnabled}">
In the latter case, changing the TextBlock's IsEnabled property will not change the hyperlink's IsEnabled property. To solve this issue, the hyperlink's IsEnabled property must be bound to the parent's property.
And here is the actual solution, all put together:
<TextBlock IsEnabled="{Binding LinkEnabled}">
<Hyperlink IsEnabled="{Binding IsEnabled, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type FrameworkElement}}}"
ToolTip="ToolTip"
ToolTipService.ShowOnDisabled="True"
ToolTipService.IsEnabled="{Binding IsEnabled, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type FrameworkElement}}, Converter={StaticResource negateConverter}}">
<TextBlock Text="{Binding Text}"/>
</Hyperlink>
</TextBlock>

Categories