Relative binding command with silverlight WP7 - silverlight

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.

Related

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

DataBinding on Custom Control Not Working

I'm sure I am doing something wrong.
Some context: WPF application, MVVM, Entity Framework, etc.
In my ViewModel for a window, I have two properties: MemberCount and EventCount. Both are int.
In my view, I have a 5 instances of a custom control. This custom control has three dependency Properties: ImageData, ButtonText, and ButtonSubText. All are string.
What I want to do is bind the control in such a way that MemberCount is bound to the ButtonText property on one control, and EventCount is Bound to ButtonText property on another control.
So I do something along the lines of:
<control:MyControl ... ButtonText="{Binding MemberCount, Mode=OneWay}" ButtonSubText="Members" Background="{DynamicResource MetroRed}" />
The DataContext of my window is set to the correct ViewModel.
No matter what I try, I cannot get the member count or event count to show up on the control. I get an error in the output window:
System.Windows.Data Error: 40 : BindingExpression path error: 'MemberCount' property
not found on 'object' ''MyControl' (Name='button')'. BindingExpression:Path=MemberCount;
DataItem='MyControl' (Name='button'); target element is 'MyControl' (Name='button');
target property is 'ButtonText' (type 'String')
I am getting used to DataBinding in WPF, but for the life of me, I can't figure this one out.
What do I need to do to be able to bind a property from my view model to a property on my custom control?
i think the problem is the datacontext or binding within your usercontrol. you should post your usercontrol code.
<MyUserControl x:Name="uc">
<TextBlock Text="{Binding ElementName=uc,Path=ButtonText}/>
</MyUserControl>
check my answer here, there is a similar problem.

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?

Binding to properties outside of the datacontext

I am creating a WPF application and am having a little difficulty implementing an user interface idea I have.
I have a MasterViewModel bound to the MainWindow which exposes an observable collection of ViewModels. I have written some commands that essentially switch the current view model in the observable collection and this subsequently displays the corresponding view. However, when the application first loads, I add a HomeViewModel to the collection which shows the Home (Navigation) View. The problem I am having is the Commands I am binding against are exposed on the MasterViewModel so they aren't 'cascading' into the items control. Can anyone offer a solution or a better one? Many Thanks.
This is the error I am receiving:
System.Windows.Data Error: 40 :
BindingExpression path error:
'MainWindowViewModel' property not found on 'object' ''HomeViewModel' (HashCode=5313339)'. BindingExpression:Path=MainWindowViewModel.LoadClientsCommand;
DataItem='HomeViewModel' (HashCode=5313339);
target element is 'Button' (Name='');
target property is 'Command' (type 'ICommand')
I believe you can access commands on the DataContext of your MasterViewModel through RelativeSource in the following way:
<Button>
<Button.Command>
<Binding Path="DataContext.MasterViewCommand">
<Binding.RelativeSource>
<RelativeSource
Mode="FindAncestor"
AncestorType="{x:Type MasterViewBaseClass}"
/>
</Binding.RelativeSource>
</Binding>
</Button.Command>
Click me!
</Button>
Can you provide code examples of your code scenario?
This reminds me of Josh Smith's MVVM example (http://msdn.microsoft.com/en-us/magazine/dd419663.aspx), mb you got your idea from there?
If I understand you correctly: Why don't you write a VM for your ItemControl and put your commands in there?
You could try to access the Commands from your ItemControl via RelativeSource (How do I use WPF bindings with RelativeSource?)

Binding to the Current Item (WPF)

I am attempting to bind a ListView control to a DataTable, but the WPF binding system seems to be complaining about the binding path I specify.
As an example, a GridViewColumn is defined as follows:
<GridViewColumn Header="ColumnTitle"
DisplayMemberBinding="{Binding Path=/,
Converter={StaticResource myConverter}}"/>
As far as I understand (and MSN seems to support me), specifying Path=/ should make the binding on the current item of the data collection.
The error I receive (in the trace window) is:
System.Windows.Data Error: 39 : BindingExpression path error: ''
property not found on 'current item of collection' ''OrdersRow'
(HashCode=680171)'. BindingExpression:Path=/; DataItem='OrdersRow'
(HashCode=680171); target element is 'TextBlock' (Name=''); target
property is 'Text' (type 'String')
This is giving me the impression that / isn't even a valid path, and WPF is expecting something after the slash. If so, how else would I bind to the current item? Why am I getting this error in the first place?
Have you tried omitting the Path parameter?
<GridViewColumn Header="ColumnTitle"
DisplayMemberBinding="{Binding Converter={StaticResource myConverter}}"/>
I think the confusion is that the DataContext for the GridViewColumn is not the top collection, but is already the item that is bound to that column, so you don't need to specify a path.
The time that the you may use a path like this is if your control's DataContext is a List and you want to bind to the selected item. A possible example would be.
<Combobox DataContext={Binding ColourList}
DataSource={Binding} <!--Bind to the datacontext -->
ForeColor={Binding/} <!--Bind to the currently selected item
in the datacontext -->
/>

Resources