I have a user control (MainView) with an other user control (GridView):
<local:MyGridView x:Name="GridView"/>
In my MainView, I have a button:
<Button Command="{Binding TestCommand}"
CommandParameter="{Binding ElementName=DataGrid}"
Content="Test"/>
In my GridView, I have a data grid that I want to send as a CommanParameter.
If the GridView code was in the MainView code, this syntax would work. What should I change?
I tried {Binding ElementName=GridView.DataGrid} - no success.
Very simple.
<local:MyGridView x:Name="**GridView**"/>
<Button Command="{Binding TestCommand}"
CommandParameter="{Binding ElementName=**GridView**}"
Content="Test"/>
You should change the ElementName from DataGrid To GridView.
You cannot use ElementName to directly reference an element that is defined in another control or namescope.
What you could do is to add a property to MyGridView.xaml.cs that exposes the DataGrid control:
public DataGrid DataGrid => dataGrid1;
You could then bind to this property of the element:
<Button Command="{Binding TestCommand}"
CommandParameter="{Binding Path=DataGrid, ElementName=GridView}"
Content="Test"/>
A better approach would be use a shared DataContext (view model) and bind both controls to properties of this one.
Related
In my project i am using the autocompletebox of the WPF toolkit from dotnetprojects:
<input:AutoCompleteBox Grid.Row="0"
Height="30"
Width="300"
ItemsSource="{Binding Persons}"
SelectedItem="{Binding SelectedName, Mode=TwoWay}"
ValueMemberPath="DisplayName"
ItemTemplate="{StaticResource AutoCompleteBoxItemTemplate}"
ItemFilter="{Binding PersonFilter}"
Style="{DynamicResource AutoCompleteBoxStyle}"
x:Name="AutoCompleteBox">
<i:Interaction.Triggers>
<i:EventTrigger EventName="TextChanged">
<i:InvokeCommandAction Command="{Binding TextChanged}"
CommandParameter="{Binding ElementName=AutoCompleteBox}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</input:AutoCompleteBox>
In the event TextChanged i pass the AutoCompleteBox as parameter to the viewmodel:
private void TextChangedInternal(object obj)
{
var box = obj as AutoCompleteBox;
...
}
From this point on i have no idea how to access the suggestion listbox within the popup.
My intention is to highlight the entered query within the suggestions.
Has somebody an idea how to archive this?
You will need to change the item template to something you control. This means you set up an AutoCompleteBox.ItemTemplate. This item template will contain each result found.
This Tutorial is for silver light but is pretty much all you need to create your custom control to highlight the text in the results. Once you have that you add this in the data template of your ItemTemplate.
I'm in my MainWindowView.xaml. It includes a usercontrol.
I'm trying to set a command with a parameter. This parameter is the selected row of a gridControl (devexpress item).
I have tried two binding, both wrong (they don't find the parameter):
<Button Command="{Binding DeleteCommand}" CommandParameter="{Binding Path=lst1, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type uc:ucImpianti}}}" Style="{DynamicResource BtnToolBar}"/>
and
<Button Command="{Binding DeleteCommand}" CommandParameter="{Binding ElementName=lst1, Path=FocusedRow}" Style="{DynamicResource BtnToolBar}"/>
How have I to write the binding to pass the selected row of a gridControl in a UC?
My command defition is:
public ICommand DeleteCommand { get; private set; }
private void DeleteRecord(object parameter)
{
Debug.WriteLine(parameter);
}
[...]
DeleteCommand = new DelegateCommand<object>(DeleteRecord, CanAlways);
It is customary in WPF to data bind a collection of a certain type to the ItemsSource property and a property of the type of object in the collection to the SelectedItem property (it makes no difference that this example uses a ListBox):
<ListBox ItemsSource="{Binding YourCollection}"
SelectedItem="{Binding YourSelectedItem}" ... />
With this set up, you can data bind directly to the YourSelectedItem property from the CommandParameter property:
<Button Command="{Binding DeleteCommand}" CommandParameter="{Binding YourSelectedItem}"
Style="{DynamicResource BtnToolBar}" />
a more general answer would be:
if you wanna access an object/property from a usercontrol, then the UserControl should expose the object/property with a Dependency Property and you can bind to this DP.
another way would be to check if the DataContext of the Usercontrol expose the property then bind to the Datacontext.Property of the usercontrol.
so for your case i would need some more information of your Viewmodel and View bindings
How can I unset the binding applied to an object so that I can apply another binding to it from a different location?
Suppose I have two data templates binded to the same object reference.
Data Template #1 is the default template to be loaded. I try to bind a button command to a Function1 from my DataContext class:
<Button Content="Button 1" CommandParameter="{Binding }" Command="{Binding DataContext.Function1, RelativeSource={RelativeSource AncestorType={x:Type Window}}}"/>
This actually works and the function gets binded. However, when I try to load Data Template # 2 to the same object (while trying to bind another button command to a different function (Function2) from my DataContext class):
<Button Content="Button 2" CommandParameter="{Binding }" Command="{Binding DataContext.Function2, RelativeSource={RelativeSource AncestorType={x:Type Window}}}" />
It doesn't work and the first binding is still the one executed. Is there a workaround to this?
EDIT (for better problem context):
I defined my templates in my Window.Resources:
<Window.Resources>
<DataTemplate DataType="{x:Type local:ViewModel1}">
<local:View1 />
</DataTemplate>
<DataTemplate DataType="{x:Type local:ViewModel2}">
<local:View2 />
</DataTemplate>
</Window.Resources>
The View1.xaml and the View2.xaml contain the button definitions that I described above (I want them to command the control of my process flow).
ViewModel1 and ViewModel2 are my ViewModels that implement the interface IPageViewModel which is the type of my variable CurrentPageViewModel.
In my XAML, I binded ContentControl to the variable CurrentPageViewModel:
<ContentControl Content="{Binding CurrentPageViewModel}" HorizontalAlignment="Center"/>
In my .CS, I have a list defined as List<IPageViewModel> PageViewModels, which I use to contain the instances of my two View Models:
PageViewModels.Add(new ViewModel1());
PageViewModels.Add(new ViewModel2());
// Set starting page
CurrentPageViewModel = PageViewModels[0];
When I try to change my CurrentPageViewModel to the other view model, this is when I want the new binding to work. Unfortunately, it doesn't. Am I doing things the right way?
If for some reason you are unable to use just two different DataTemplates, usually because the datatemplates are very large or complex, i suggest using ContentControl and DataTemplateSelector.
In your DataTemplates place another ContentControl, create 2 DataTemplates just containing your button, one with Function1 one with Function2. Create a DataTemplateSelector and set it on the initial ContentControl. The DataTemplateSelector now just need to select the proper template depending on a decision, for example the type of the item or a property on the item etc.
If you still want to unset binding you can do it from code like:
BindingOperations.ClearBinding(txtName, TextBox.TextProperty)
But TemplateSelector approach will be more efficient.
I have two user controls LeftPanel and DeviceList. DeviceList is inside the LeftPanel. I want the context menu in device list to be able to call a command on the parent view model, which is set on a grid that hosts DeviceList. I have tried the following but it does not work.
Here is the ContextMenu within DeviceList
<MenuItem Command="{Binding RelativeSource={RelativeSource Mode=FindAncestor,
AncestorType={x:Type local:LeftPanel}},
Path=DeviceListViewModel.RemoveDevice}">
Here is the LeftPanel usercontrol
<UserControl x:Class="Tool.LeftPanel" .... >
<Grid DataContext="{Binding DeviceListViewModel}" Grid.Column="1">
<local:DeviceList Grid.Row="1" Margin="0,0,0,10"/>
I had a similar problem, but the ContextMenu does not see the DataContext of the ViewModel or the Parent.
A possible solution is here Access ViewModel / DataConext inside ContextMenu .
the contextmenu is not part of the visualtree, so i think your binding is simply wrong because the datacontext is not what you think of.
use Snoop to check your DataContext and bindings at runtime
i assume that you have to work with PlacementTarget in your bindings
This is my xaml
<ListBox x:Name="HistoryList"
ItemsSource="{Binding HistoryCollection}"
>
<ListBox.ItemTemplate >
</DataTemplate>
<CheckBox x:Name="UpCheckBox" Height="50" Width="50" >
<interactivity:Interaction.Triggers>
<interactivity:EventTrigger EventName="Checked">
<interactivity:InvokeCommandAction Command="{Binding UpCheckedCommad}" CommandParameter="{Binding ElementName=UpCheckBox}"></interactivity:InvokeCommandAction>
</interactivity:EventTrigger>
</interactivity:Interaction.Triggers>
</CheckBox>
</DataTemplate>
</ListBox.ItemTemplate >
</ListBox >
In ViewModel I have used GalasoftMVVM Command Binding
public ICommand UpCheckedCommad
{
get { return new RelayCommand<Object>(x => { PerformUpforTracks(x); }); }
}
void PerformUpforTracks(object x)
{
//TODO
}
I used a CheckBox inside a ListBox ItemTemplate.But am not getting the Checked Event of CheckBox in the ViewModel .
I wanted to get the Checked Event from my ViewModel.Can anyone have any idea to resolve this issue?
Each instance of your ListBox.ItemTemplate is automatically given "the current item in the collection" as its DataContext. In your case, that is each individual item in the HistoryCollection. In your example, the EventTrigger is searching for the "ThumbsUpCheckedCommad" inside your current instance of the HistoryItem.
In order to force the EventTrigger to search in your desired ViewModel, you need to specify the "Source" property of your command binding. I suggest using the RelativeSource syntax, to search up the tree for the last Control to have your ViewModel as its DataContext.
It would look something like this.
{Binding Path=ThumbsUpCheckedCommand, RelativeSource={RelativeSource AncestorType={x:Type ListBox}}}
I got it By Binding Command by this way
Command="{Binding Path=DataContext.UpCheckedCommad,
ElementName=HistoryList}"