WPF binding Ancestor - wpf

I have problems with bindings. I want to use a UserControl (Intellibox from codeplex) but I only get error messages in the output window.
Basically I have
window grid ... stuff ... usercontrol (self written) ... stuff ... usercontrol (IntelliBox)
In the Output window I get following stuff:
System.Windows.Data Error: 4 : Cannot find source for binding with reference
'RelativeSource FindAncestor, AncestorType='System.Windows.Controls.UserControl',
AncestorLevel='1''. BindingExpression:Path=ShowResults; DataItem=null;
target element is 'Popup' (Name='IntelliboxPopup1');
target property is 'IsOpen' (type 'Boolean')
The binding in the IntelliBox control is defined as follows:
{Binding Path=ShowResults, RelativeSource={RelativeSource FindAncestor,
AncestorType={x:Type UserControl}}}
I guess there is a problem, cause the nesting withing usercontrols - how to I get this error fixed?
Thanks!

I have two questions. First, is this a Binding that you wrote for your use, or is it something that came out-of-the-box inside the UserControl you're using? Second, are you trying to Bind to the Intellibox, or to your "self written" UserControl?
Assuming it's a Binding you wrote for your use (I don't have knowledge of Intellibox so I wouldn't know where to start for fixing it), there are a couple of solutions you might try.
First, when binding to an ancestor, try using the exact ancestor type. For instance, if you're binding to the Intellibox, use AncestorType={x:Type Intellibox}. Otherwise use AncestorType={x:Type <YourType>}. Your Binding will be less ambiguous this way.
Second, and perhaps the best answer in this case, is to bind to the control you want by name by setting x:Name="BindSource (or whatever)" on the target and using the Binding syntax:
{Binding Path=ShowResults,
ElementName=BindSource}
--
HTH,
Dusty

Related

Styles and DataTemplates: FindAncestor-like search including Self

I have a style containing binds expression of the form
{Binding Path, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type MyType}}}
However, sometimes the DataContext in which this style operates is actually of type MyType. In this case, FindAncestor doesn't do what I want: it starts its search from the parent.
Is there any {Binding ...} incantation that checks the type of the current datacontext before continuing up the element hierarchy? I have other solutions specific to my project, but FindAncestor is so close...
RelativeSource bindings do not look for DataContexts, they search the visual tree for UI elements. The AncestorType should be a control.
To perform a RelativeSource binding on the same control you can use RelativeSource Self

{Binding DataContext.foo} vs {Binding foo} Difference

I thought {Binding DataContext.foo} and {Binding foo} were identical until I came across an issue binding a selection changed event from a ComboBox to a command in my ViewModel.
I was doing it like so...
<i:EventTrigger EventName="SelectionChanged">
<cmd:EventToCommand Command="{Binding DataContext.TestCommand, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Page}}}" />
</i:EventTrigger>
Using DataContext.TestCommand works while just specifying TestCommand appears to fail. I've never encountered a difference between the two can anyone explain it?
They're binding to two subtly different things:
"Binding DataContext.TestCommand" is binding to the TestCommand property of the Datacontext (presumably the context defines that property) of your Page.
"Binding TestCommand" is binding to the TestCommand property of the Page itself, which in this case probably doesn't exist, which is why it doesn't work.
There's a neat program called WPF Snoop that you can use to inspect the bindings whilst things are running (often helps me make sense of things when I'm, stuck).
Almost each element in visual tree (View) is linked to the data layer (ViewModel) per DataContext property. Of course the data layer tree is much more simpler because most controls just inherit from their parent.
By default a Binding is looking for the Path in data layer. But if you specify a RelativeSource (like RelativeSource.Self or with AncestorType) or an ElementName the Binding switches to visual layer and searches in controls for the bound property. With DataContext you can go back to data layer.

WPF Element Binding

I have two controls within my UserControl where I bind to the exact same object using Element Binding:
AllowNext="{Binding ElementName=MainGrid, Path=DataContext.CanContinue}"
On the first control it works fine but on the second I get a binding exception:
System.Windows.Data Error: 4 : Cannot find source for binding with reference 'ElementName=MainGrid'. BindingExpression:Path=DataContext.CanContinue; DataItem=null; target element is 'WizardPage' (Name='DeductionPage'); target property is 'AllowNext' (type 'Boolean')
I have also tried using RelativeSource binding on the second control:
AllowNext="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Grid}}, Path=DataContext.CanContinue}"
But this also gives me an error.
Does anyone know what this might be?
--
Here is the simplified control:
<Grid Name="MainGrid">
<w:Wizard Name="MyWizard" w:Designer.PageIndex="1" DataContext="{Binding ElementName=MainGrid, Path=DataContext.Policy}" >
<w:WizardPage Header="Main Member" MaxHeight="600" AllowNext="{Binding ElementName=MainGrid, Path=DataContext.CanContinue}" Name="MainPage">
</w:WizardPage>
<w:WizardPage Name="DeductionPage" Header="Policy Details" AllowBack="False" AllowNext="{Binding ElementName=MainGrid, Path=DataContext.CanContinue}">
</w:WizardPage>
</w:Wizard>
</Grid>
Now as I mentioned, MainPage binds fine, whereas the DeductionPage does not bind at all and gets the supplied error. The DataContext of MainGrid is set from code behind:
public void SetDataContext(object o)
{
MainGrid.DataContext = o;
}
I bet it's the MainGrid which is the binding source is not in the logical tree of your binding target.
This is the problem absolutely with the binding element. However, you didn't give the source so You want to debug it and solve the issue.
Refer the below url and "Cannot find source for binding with reference" section where explained obviously how to debug and solve it.
http://www.codeproject.com/Articles/244107/Debugging-WPF-data-bindings

what is the meaning of relative source Ancestor Type?

here ,i know that relative source use as getting value with respect to the other but i can not get meaning of the RelativeSource AncestorType={x:Type UserControl}}
Value="{Binding Path=DataContext.ItemOptions, RelativeSource={RelativeSource AncestorType={x:Type UserControl}}
plz explain it .i think it is a trivial .u can explain me.
It tells WPF to walk up the tree of 'parents' from the current control andfind the first one of type UserControl. In this case, the binding is to that ItemOptions property of that usercontrol's DataContext

WPF Binding to Window property failing

I've got a custom control class in my project called "CarSystemWindow". It descends from Window and has a custom template that gives all windows in my application the same look. It also defines two dependency properties named DeviceName and DeviceType. These are of type string. They default to "Vehicle: " and "Car 54", respectively.
In my main program, I retrieve a row from my database into a View Model object and save that in a normal CLR property called Site during the program's initialization. In the MainWindow's xaml, I have the following code:
<cs:CarSystemWindow x:Class="....MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:c="clr-namespace:..."
xmlns:cs="..."
Background="Black"
Closed="Window_Closed"
DataContext="{Binding Path=Site, RelativeSource={RelativeSource AncestorType={x:Type Window}}}"
DeviceName="{Binding Path=SiteName}"
DeviceType="{Binding Path=SiteTypeName}"
Icon="..."
Height="600"
Loaded="Window_Loaded"
ResizeMode="CanMinimize"
SourceInitialized="Window_SourceInitialized"
Title="Window Title"
Width="800"
WindowStartupLocation="CenterScreen">
At run time, the binding on the DataContext attribute is failing with the following message:
System.Windows.Data Error: 4 : Cannot find source for binding with reference 'RelativeSource FindAncestor, AncestorType='System.Windows.Window', AncestorLevel='1''. BindingExpression:Path=Site; DataItem=null; target element is 'MainWindow' (Name=''); target property is 'DataContext' (type 'Object')
I'm using this same binding code elsewhere and it works. I've even turned the Site property into a dependency property and its still failing.
Does anyone give have ideas why the binding is failing?
Thanks
Tony
I think you need to change your binding to this:
{Binding RelativeSource={RelativeSource Self}, Path=Site}
The reason your current binding is not working is that you are trying to go up a level in the hierarchy from the Window, but you actually want the Window.
Here is a good source for figuring out what the binding string should be for different scenarios:
http://www.nbdtech.com/Free/WpfBinding.pdf
The problem with the DataContext binding is that the line is saying to use the Site property on an object that is an ancestor of this object, and of type Window. Since this object is a Window already, and therefore at the root of the visual tree, there are no ancestors to search and find the specified property.
Why don't you assign the DataContext where this object is constructed?

Resources