WPF Binding CommandParameter to Element of perent window - c#

I build some WPF application that as MainView, inside this MainView I have a button that opens a setting window and a Model that I want to be able to show or hide from this settings view. (the show/hide button was originally on the MainView itself) the problem is that I do not know how to use the CommandParameter in the SettingsView to bind to an element In the MainViw.
the element in the MainView:
<Dev:DevUnitView x:Name="DevData" DataContext="{Binding MainModel.DevUnit}" Visibility="Visible" Margin="994,656,74,-83"/>
the button in the SettingsView:
<Button Content="Show/Hide debug values" Command="{Binding Settings.DevVisibilityCommand}" CommandParameter="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Dev:DevUnitView}}, Path=DataContext}" Margin="156,22,180,349"/>
I also tried to Bind to the MainView but I do not know how to find the element I need from there:
CommandParameter="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type mainWindow:MainView}}, Path=DevUnit}"
in this case, it cannot resolve the "DevUnit" in the data context, I also tried by name and other variation of this without success.
the old button that worked in the MainView:
<Button Content="DEV" Command="{Binding Settings.DevVisibilityCommand}" CommandParameter="{Binding ElementName=DevData}" Margin="406,359,810,259"/>
now no matter how I try to bind it I getting Null UserControl.

Related

WPF Datagrid ContextMenu SelectedItem

I have the following problem.
I have a DataGrid with a ContextMenu. But when the Command is triggered the SelectedItem is always null. Any recommendations?
Thats my ContextMenu:
<DataGrid.ContextMenu>
<ContextMenu>
<MenuItem Command="{Binding OpenFileCommand}"
CommandParameter="{Binding Path=SelectedItem,
RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}"
Header="open file" />
i also tried:
CommandParameter="{Binding ElementName=nameOfGrid, Path=SelectedItem}"
Thanks for your help. I fixed it this way: CommandParameter="{Binding PlacementTarget.SelectedItem,
RelativeSource={RelativeSource FindAncestor,
AncestorType={x:Type ContextMenu}}}"
I think your answer is here: CommandParameters in ContextMenu in WPF
Another better option imho is to keep "SelectedItem" binded in your ViewModel.
Then you don't need a command parameter anymore, and you can juste use the SelectedItem binded from your ViewModel.
The problem is that the ContextMenu is in a different VisualTree.
You could use the Tag for binding the Command. See the following link

How to use EventToCommand - Error in XAML

The user input something in the TextBox and hits the Enter-button. When the Enter-button is hit the AddFieldCommand is called. How do I do what in XAML?
My code is giving me a warning: "The Property 'Text' is set more than once".
I need to know which object in the Canvas that is being updated, so I can add the content from the TextBox to my model - this is why I use EventToCommand.
<TextBox x:Name="txtFields" Text="{Binding FieldsTextProperty, UpdateSourceTrigger=PropertyChanged}" Height="23" TextWrapping="NoWrap" Background="#FFCBEECD" AcceptsReturn="False" >
<TextBox.InputBindings>
<KeyBinding Key="Enter" >
</KeyBinding>
</TextBox.InputBindings>
<i:EventTrigger EventName="AddField">
<cmd:EventToCommand Command="{Binding DataContext.AddFieldCommand, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}}" PassEventArgsToCommand="True"/>
</i:EventTrigger>
</TextBox>
Can anybody help?
In XAML, everything that’s placed inside an element becomes its content. For text boxes, this sets the Text property. This is to allow things like this:
<TextBox>Foo bar</TextBox>
So you can place the content within the XAML elements. This is equivalent to this:
<TextBox Text="Foo bar" />
Now, if you look at your XAML code, you will notice that you have two elements inside the TextBox element: TextBox.InputBindings and i:EventTrigger. To explain the first, you need to know that there is another way to specify an element’s property values, by using child elements. This makes the above examples equivalent to this:
<TextBox>
<TextBox.Text>Foo bar</TextBox.Text>
</TextBox>
This works for all properties of TextBox. Now, InputBindings is an property of TextBox, so having it as a child element will correctly set the property and it will also not affect the element’s content value (so Text isn’t set by its presence). However, i:EventTrigger is not an property of TextBox, so this will set the content of the TextBox—giving the error message you see.
To use interaction event triggers, you need to place these into the attached property i:Interaction.Triggers. As an attached property, it can be set with a child element like above. So, your code should look like this:
<TextBox …>
<i:Interaction.Triggers>
<i:EventTrigger EventName="AddField">
<cmd:EventToCommand … />
</i:EventTrigger>
</i:Interaction.Triggers>
</TextBox>
You can use ICommand interface to execute your command and use IsDefault=true property of the button which allows it to remain focus.So when you click enter it will execute the Command you binded on the button.
<TextBox x:Name="txtFields" Text="{Binding FieldsTextProperty,UpdateSourceTrigger=PropertyChanged}" Height="23" TextWrapping="NoWrap" Background="#FFCBEECD" AcceptsReturn="False" />
<Button Name="btnEnter" IsDefault="True" Command="{Binding DataContext.AddFieldCommand, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}}" />

Cannot bind command within a ListBox

My WPF uses the MVVM approach. I'm trying to bind 2 controls within my list control
<ListBox ItemsSource="{Binding ParentDuplicate}" SelectedItem="{Binding SelectedParent, UpdateSourceTrigger=PropertyChanged}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<ContentControl Content="{Binding}" />
<Button Content="Delete me now"
Command="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorLevel=1, AncestorType=Window}, Path=DeleteCommand}"
CommandParameter="{Binding FilePath}" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
The problem I'm having, is the DeleteCommand is not binding (the Ouput window informs me as well)
System.Windows.Data Error: 4 : Cannot find source for binding with reference 'RelativeSource FindAncestor, AncestorType='System.Windows.Data.Binding', AncestorLevel='1''. BindingExpression:Path=DeleteCommand; DataItem=null; target element is 'Button' (Name=''); target property is 'Command' (type 'ICommand')
If I move this button to outside the ListBox, then the binding works and the event fires so I know the issue must be with the ListBox (I'm guessing the problem is the ItemsSource prevents the binding to anything but the ItemsSource bound property (in this case, ParentDuplicate))
So, within the Button control, there are 2 properties being bound, DeleteCommand and FilePath
Both of these properties live within my single ViewModel. FilePath is a child of ParentDuplicate and this binds as desired. The issue is only with the DeleteCommand. What am I doing wrong?
Edit
When I use the Command="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorLevel=1, AncestorType=Window}, Path=DeleteCommand} it is looking in my MainWindow code behind, not at the ViewModel. How do I make it use the ViewModel?
I tried
Command="{Binding RelativeSource={RelativeSource AncestorType=xmlnsViewModel:MainWindowViewModel}, Path=DeleteCommand}"
but the above also results in the same binding errors
The ancestor search finds the control, not the DataContext, so you'll need to tell your binding where to find the DeleteCommand property. If your ViewModel is the DataContext of the MainWindow then you can just use:
<Button Content="Delete me now"
Command="{Binding RelativeSource={RelativeSource
Mode=FindAncestor, AncestorLevel=1, AncestorType=Window},
Path=DataContext.DeleteCommand}"
CommandParameter="{Binding FilePath}" />

UserControl doesn't display inside a window

After many searches here and also in tutorials i came up empty handed and would very appreciate help:
I have a UserControl that contains a list of other kind of UserControls.
I want to display this UserControl inside a regular WPF window:
This is the UserControl that contains the list of UserControls:
<UserControl x:Class="UsersInfo.InfoLinesContainer"...
...
<Grid>
<ListView ItemsSource="{Binding Path=InfoLineUC_ObservableList,RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type UserControl}}}">
</ListView>
</Grid>
And in my main window i do:
<Window x:Class="UsersInfo.MainAppWindow"
...
xmlns:usrCtr ="clr-namespace:UsersInfo"
...
<usrCtr:InfoLinesContainer Grid.Row="11"
DataContext="{Binding Path=TheInfoLines, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type UserControl}}}"
ScrollViewer.CanContentScroll="True" Margin="2" Grid.ColumnSpan="7" Grid.RowSpan="6" />
...
TheInfoLines is the instance of the UserControl that contains the list of other UserControls
When i run the program the window comes up without the UserControl inside it(all i get is an empty square)
How can i make it work?
In your main window :
<usrCtr:InfoLinesContainer DataContext="{Binding Path=TheInfoLines, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type UserControl}}}" />
What are you trying to bind here ? There seems to be no ancestor of type UserControl in your window.

How to get selectedItem from ListView from a button click in the listView Item

I have a list view item which has a button and displays properties on an object. I have the command property set up for the button using the mvvm pattern which fires correctly.
My issues is that when a press the button it does not also get the selected item, I am guessing that it has not fired the selectedItem event.
Is it possible to force this event when the button is pressed?
<Button
Height="20"
Width="20"
Grid.Column="3"
Grid.Row="0"
Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=DataContext.RemoveClick}"
CommandParameter="{Binding SelectedItem, ElementName=serverListView, Mode=TwoWay}">
You may :
- set the commandParameter of your command to {Binding}
- Bind the SelectedItem to some Property of your VM
- Set this property to the command parameter in the begining of your command execute method

Categories