How to pass an entire view in ContextMenu? - xaml

I am using context menu on a datagrid for copy/paste. But I am not getting my current view in ContextMenu's Command Parameter.In other command bindings I have passed my View name as Command parameter to get the current view status. But now I am stuck with this ContextMenu as I am not able to pass my view through it. I am using MVVM.
My snippet is
<DataGrid.ContextMenu>
<ContextMenu x:Name="_menu">
<MenuItem Header="Copy" Command="{Binding CopyCommand}"
CommandParameter="{Binding RelativeSource={RelativeSource AncestorType={x:Type Window}},Path=DataContext}" />
</ContextMenu>
</DataGrid.ContextMenu>

The best way (in my opinion) is to declare your ViewModel as a static resource within your page. Then you can bind your root panel's DataContext to this static resource (getting you to where you are now). This then has the added benefit of making the binding work in your CommandParameter (by binding the parameter to a StaticResource rather than using FindAncestor).
The most probable reason why your current Binding expression isnt working is that your hit a template encapsulation boundary, but I cant be sure without seeing all of the code

<DataGrid.ContextMenu>
<ContextMenu x:Name="_menu">
<MenuItem Header="Copy" Command="{Binding CopyCommand}"
CommandParameter="{Binding RelativeSource={RelativeSource AncestorType={x:Type ContextMenu}},Path=PlacementTarget.DataContext}" />
</ContextMenu>
</DataGrid.ContextMenu>
i assume that your datagrid is in your current view

Related

.NET MAUI Communitytoolkit.Mvvm: How to bind an object instead of a string

i already the project from the official tutorial of .NET MAUI until step 5 using Communitytoolkit.Mvvm:
text
Now, instead of binding only a Text (which is a standard type that can be accessed from everywhere) i would like to bind a simple object (called ItemGroup) with two members (bool isChecked and string name).
How to do that?
For a global access i made this class in the MainView folder called ItemGroup. This class is not accessable and i don't know how to do that it is.
I changed the code in the MainPage.xaml like this:
<CollectionView ItemsSource="{Binding Items}"
Grid.Row="1">
<CollectionView.ItemTemplate>
<DataTemplate x:DataType="{x:Type x:ViewModel.ItemGroup}">
<Grid >
<CheckBox IsChecked="{Binding ItemGroup.IsChecked}" Grid.Column="0"/>
<Label Text="{Binding ItemGroup.name}" Padding="10" Grid.Column="1"
BackgroundColor="LightGray"/>
</Grid>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
See also the project structure with the ItemGroup class in the ViewModel folder as well as the error message:
where the content page is declared as this:
Remark: The MainViewModel looks like this:
Should i declare some uses, or namespace?
where in the project should i place the Class of the objects i would bind?
Thanks in advance, Thomas
Also tryed to implement the class ItemGroup in the MainViewModel.cs but then i had any more problems with access to this class.
Try this
<Label Text="{Binding name}" …
Note that name must be a public property
You have a number of issues here.
The community mvvm toolkit includes code generators.
A variable:
[ObservableProperty]
string text;
Is examined by the code generator at compile time and in a partial class it will add a public property Text.
Binding is case sensitive and you need to bind to public properties so you need to use upper case on that first letter. Binding Text rather than Binding text.
You might have other instances where you did the same sort of thing.
I don't see where you use it but that add [Relaycommand] will generate AddCommand as a public property which you bind to.
Additionally you have misunderstood how an itemscontrol gets an item out a bound collection per row. As DevenCC points out, once you bind ItemsSource to Items then each row will get an instance of whatever is in that collection so you should bind IsChecked rather than ParentProperty.IsChecked.
As to where to put classes. In large apps it is a nuisance to flip between a folder contains views and another contains viewmodels. You might want to consider a folder contains each pair of view and viewmodel. Hence a foo folder containing fooView and fooViewModel
I believe your problem lies with you Binding declaration inside you ItemTemplate. Given that you bound your CollectionView's ItemSource to "items", the ItemTemplate's data context is now a single itemGroup from your list. Therefore, you should not be writing
<CheckBox IsChecked="{Binding ItemGroup.IsChecked}"[...]
But instead
<CheckBox IsChecked="{Binding isChecked}"[...]
Since you are already "within" a single itemgroup object. Same goes for your Label. Furthermore, I don't think you actually need to declare the Datatype for your item's DataTemplate.
p.s. Watch out for your item declaration, it seems like you have both items and Items declared in your ViewModel; and both seem public.

How to get the "{Binding}" instance from within the behavior?

I created a behavior to validate a control whenever there's an error. The behavior needs to know the Binding (viewmodel) source of the control because the ViewModel implements IDataErrorInfo and the behavior needs to subscribe to the ErrorChanged event to make the appropriate action when an error occurs.
To do that, I added a dependency property ValidationSource which will always be set to "{Binding}".
<TextBox Text="{Binding LastName, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}">
<i:Interaction.Behaviors>
<b:MyValidateOnErrorBehavior PropertyName="LastName" ValidationSource="{Binding}" />
</i:Interaction.Behaviors>
</TextBox>
This solution works for me but I don't want to type ValidationSource="{Binding}" all the time.
Is there a way from within the behavior to get to the "{Binding}" instance without having to set it in the dependency property?
In the Behavior's code you can get the AssociatedObject.DataContext to get that - which would be your ViewModel.

Order of bindings in Windows Phone 8

I am facing this issue regarding data binding and binding in a converter while developing a Windows Phone 8 app.
I am trying to send the button to a converter so I can access all of its properties using the following code
<Button Content="{Binding OwnBoard, Mode=OneWay}" Grid.Row="0" Background="{Binding RelativeSource={RelativeSource Mode=Self}, Converter={StaticResource BoardToBackConv}}" />
When I hit the break point in the converter I have the button as the binding object, but the Content property of the control is Null. I need to access the object stored in the Content property.
As far as I know, because of the order of the bindings, the Content property should already contain a value.
Any idea how to make this work?
I have managed to understand why what I want to do is not going to work.
Keeping it short, the converter is executed during the InitializeComponent() call, and at that time the other binding was not done, because there is not DataContext for the view yet.

How to reuse XAML code blocks without binding?

I have this XAML code block:
<StackPanel Orientation="Horizontal">
<TextBlock Text="Hello " />
<TextBlock Text="World" />
</StackPanel>
I would like to define this block (for example in /Common/CustomStyles.xaml) to include it on different XAML pages. How does it work?
I do not need a DataTemplate or something similar because the text is static.
You could put it in a user control and re-use it that way. If it's just the text you are interested in then you could use a resource file - this would update the textbox on any screen as long as it had the right uid.

Silverlight - displaying graphical resources within a button

Has anyone solved this: displaying graphical resources within a button
create a resource, for instance a rectangle
<UserControl.Resources>
<Rectangle x:Key="myRectangle" Fill="Red" Height="100" Width="100"/>
</UserControl.Resources>
then set the content of the button to the resource
<Button Content="{StaticResource myRectangle}"/>
when you build inside blend 4 RC you get the error "Value does not fall within the expected range."
Visual studio does not show this error.
When you run the site the button doesn't show any content.
This technique works in WPF without problems.
Anyone got any ideas?
This can be done by directly setting the shape as the button's content. For eg:
<Button Height="120" Width="120">
<Rectangle Fill="Red" Height="100" Width="100"/>
</Button>
FrameworkElement.Resources are generally used for storing nonvisual elements, brushes, etc. For your case (I think) you'll need to store your xaml as a data template, again not sure if this works with Buttons, it is used for things like ListBoxes. See here:
resources description on msdn. The link further contains pointers to information for Data Templates etc.