Binding to dependency property via PlacementTarget fails - wrong path syntax? - wpf

No problem
I created a dependency property which takes a string value. I set it on a TextBlock and it works:
<TextBlock dp:ElementDataContext.ElementName="LvMain">
I verified that the property ElementDataContext.ElementName is set to "LvMain".
Problem
Now here is the problem: in the TextBlock's context menu I want to bind to this dependency property via PlacementTarget.
Here is how I try to do it. This is an excerpt of my XAML containing TextBlock and ContextMenu:
<TextBlock dp:ElementDataContext.ElementName="LvMain">
<TextBlock.ContextMenu>
<ContextMenu Tag="{Binding PlacementTarget.(dp:ElementDataContext.ElementName), RelativeSource={RelativeSource Self}}">
This fails at runtime. When opening the context menu it gives me a "BindingExpression path error":
BindingExpression path error: '(dp:ElementDataContext.ElementName)' property not found on 'object' ''TextBlock' (Name='')'. BindingExpression:Path=PlacementTarget.(dp:ElementDataContext.ElementName); DataItem='ContextMenu' (Name='contextMenu'); target element is 'ContextMenu' (Name='contextMenu'); target property is 'Tag' (type 'Object')
I suspect my binding path is wrong. I tried
PlacementTarget.(dp:ElementDataContext.ElementName)
PlacementTarget.dp:ElementDataContext.ElementName
PlacementTarget.ElementDataContext.ElementName
Nothing works. What is the correct syntax? Is this even possible?

The property path syntax PlacementTarget.(dp:ElementDataContext.ElementName) is correct, but you also have to explicitly write the Path=... part in the property expression:
<ContextMenu Tag="{Binding Path=PlacementTarget.(dp:ElementDataContext.ElementName),
RelativeSource={RelativeSource Self}}">
However, the Implicit Path section in Binding Markup Extension does not mention this behaviour.

Related

Binding Error Reported with Converter in WPF Textbox

a textbox is either hidden or not depending on whether its text is null or not.
The actual hiding works ok but i keep getting a Data.Error as follows.
System.Windows.Data Error: 40 : BindingExpression path error: 'new_file_path' property not found on 'object' ''main_window_vm' (HashCode=44962972)'. BindingExpression:Path=new_file_path; DataItem='main_window_vm' (HashCode=44962972); target element is 'Run' (HashCode=28141317); target property is 'Text' (type 'String')
xaml is
<Padding="10" Visibility="{Binding Path=Text, RelativeSource={RelativeSource Self},
Converter={StaticResource null_to_viz}}">
<Run Text="Updated file path : " />
<Run Text="{Binding new_file_path}" />
any ideas to fix this error?
The issue is complaining about not finding new_file_path yet the example is binding to the property Text.
Most likely this converter is not failing and it is a different control. Investigate by either finding the right control which is not binding properly or verifying that textbox is actually binding to the proper VM.
seems like this error occurs when one foolishly set a property to private, not public. Which is why it was not able to be found.

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

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?

Relative binding command with silverlight WP7

I have an error when binding my command to a button in an ItemsControl.
This is my code :
<phone:PhoneApplicationPage.DataContext>
<ViewModel:MyViewModel />
</phone:PhoneApplicationPage.DataContext>
with :
<ItemsControl ItemsSource="{Binding MyList}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Button Content="Test"
cmd:ButtonBaseExtensions.Command="{Binding MyViewModel.TestCommand}"
cmd:ButtonBaseExtensions.CommandParameter="{Binding}"/>
</ItemsControl.ItemTemplate>
</ItemsControl>
And I get :
System.Windows.Data Error: BindingExpression path error: 'MyViewModel' property not found on '...' '...' (HashCode=77119633). BindingExpression: Path='MyViewModel.ChooseCommand' DataItem='...' (HashCode=77119633); target element is 'System.Windows.Controls.Button' (Name=''); target property is 'Command' (type 'System.Windows.Input.ICommand')..
Of course, I should use an absolute binding or a relative one, but I don't know how to do that.
Thanks in advance for any help
Your Button is within an ItemsControl which is bound to youur MyList property, which I am guessing is a List or some IEnumerable type. The DataContext of each Button will be the item within the MyList that it represents.
You are correct that to bind the buttons to your top-level view model you would need some sort of relative source binding, which Silverlight (3) does not support.
I created a relative source binding replacement for Silverlight here:
http://www.scottlogic.co.uk/blog/colin/2009/02/relativesource-binding-in-silverlight/
However, for WP7, where performance really matters, I would not use it!
Why not simply create the relationship you need in your view model? i.e. for each item in MyList (let's call them MyListItem), expose a property which points back to the parent view Model. In other Words, have a MyListItem.Parent property which points to MyViewModel.

how to use isChecked as a command parameter in that same check boxes command

So I have a check box that fires a command using WPF/MVVM this works fine but I want to use the IsChecked property of the check box as a command parameter. I tried this.
<CheckBox Margin="3" Content="Clear Selected OEM"
Command="{Binding Path=ClearOemCommand}"
CommandParameter="{Binding Path=IsChecked}"/>
Bu I get an error in the output window that says
System.Windows.Data Error: 40 : BindingExpression path error: 'IsChecked' property not found on 'object'
I would know how to use find ancestor if I wanted to use the property from another control but I am stumped here - it's probably easier than I think... Just not making the connection in my mind.
Thanks!
Please add RelativeSource Self in CommandParameter
<CheckBox Margin="3" Content="Clear Selected OEM"
Command="{Binding Path=ClearOemCommand}"
CommandParameter="{Binding Path=IsChecked, RelativeSource={RelativeSource Self}}" />
If you run into the following exception, as I did...
Set property System.Windows.Data.Binding.RelativeSource threw an exception
Try this instead:
CommandParameter="{Binding RelativeSource={RelativeSource Self}, Path=IsChecked}"
Yes JW1 is correct. You can use elemen name too like this, that would also work
"{Binding Path=IsChecked,ElementName=chkAll}"
Instead of creating command on CheckBox you can bind IsChecked with a CLR property and perform your command logic on setter of CLR property. This is another workaround of handing of command behavior.

Resources