Flyout Page not responding - maui

I'm starting understanding .Net MAUI with an online video.
I'm trying to customize a page with 3 buttons, 1 for a counter, 1 for a second page and 1 for a flyoutpage.
Counter and second page are ok, flyout page doesn't display but force the App to exit.
My code for the button that calls the flyout page is this, located in the MainPage.xml.cs :
private void FlyClicked(object sender, EventArgs e)
{
Navigation.PushAsync(new Flyout1());
}
Can anybody explain me the reason of this ?
Many Thanks

According to your description, the Flyout1 should be a FlyoutPage. You can refer to the code below on how to create a FlyoutPage. I test it and it can display it.
Flyout1:
XAML:
<?xml version="1.0" encoding="utf-8" ?>
<FlyoutPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MauiAppDualScreen.Flyout1"
xmlns:local="clr-namespace:MauiAppDualScreen"
>
<FlyoutPage.Flyout>
<local:FlyoutMenuPage x:Name="flyoutPage" />
</FlyoutPage.Flyout>
<FlyoutPage.Detail>
<NavigationPage>
<x:Arguments>
<local:MainPage />
</x:Arguments>
</NavigationPage>
</FlyoutPage.Detail>
</FlyoutPage>
Code-behind:
public partial class Flyout1 : FlyoutPage
{
      public Flyout1()
      {
            InitializeComponent();
}
}
The following example shows the definition of the FlyoutMenuPage object, which is of type ContentPage:
XAML:
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MauiAppDualScreen.FlyoutMenuPage"
xmlns:local="clr-namespace:MauiAppDualScreen"
Title="FlyoutMenuPage">
<CollectionView x:Name="collectionView"
x:FieldModifier="public"
SelectionMode="Single">
<CollectionView.ItemsSource>
<x:Array Type="{x:Type local:FlyoutPageItem}">
<local:FlyoutPageItem Title="Contacts"
IconSource="dotnet_bot.png"
TargetType="{x:Type local:MainPage}" />
<local:FlyoutPageItem Title="TodoList"
IconSource="dotnet_bot.png"
TargetType="{x:Type local:MainPage}" />
<local:FlyoutPageItem Title="Reminders"
IconSource="dotnet_bot.png"
TargetType="{x:Type local:MainPage}" />
</x:Array>
</CollectionView.ItemsSource>
<CollectionView.ItemTemplate>
<DataTemplate>
<Grid Padding="5,10">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="30"/>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Image Source="{Binding IconSource}" />
<Label Grid.Column="1"
Margin="20,0"
Text="{Binding Title}"
FontSize="20"
FontAttributes="Bold"
VerticalOptions="Center" />
</Grid>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
</ContentPage>
Code-behind:
public partial class FlyoutMenuPage : ContentPage
{
      public FlyoutMenuPage()
      {
            InitializeComponent();
      }
}
The flyout page consists of a CollectionView that's populated with data by setting its ItemsSource property to an array of FlyoutPageItem objects. The following example shows the definition of the FlyoutPageItem class:
public class FlyoutPageItem
{
public string Title { get; set; }
public string IconSource { get; set; }
public Type TargetType { get; set; }
}

Related

Xamarin forms same listview in different views [duplicate]

I have written a nice Grid with some other controls like: Entry and Image and now I would like to reuse it the simplest way.
This is my control for Email property:
<Grid
Style="{StaticResource gridEntryStyle}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="9*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="20" />
<RowDefinition Height="7" />
<RowDefinition Height="20" />
</Grid.RowDefinitions>
<controls:ExtendedEntry
Grid.Row="0"
Grid.Column="0"
Text="{Binding UserEmail, Mode=TwoWay}"
Placeholder="{i18n:Translate UserEmailPlaceholder}"
Style="{StaticResource entryStyle}">
<controls:ExtendedEntry.Behaviors>
<behavior:EventToCommandBehavior
EventName="Focused"
Command="{Binding ControlFocusCommand}"
CommandParameter="UserEmail"/>
<behavior:EventToCommandBehavior
EventName="Unfocused"
Command="{Binding ControlUnfocusedCommand}"
CommandParameter="UserEmail"/>
</controls:ExtendedEntry.Behaviors>
</controls:ExtendedEntry>
<Image
Grid.Row="0"
Grid.Column="1"
Source="clear.png"
IsVisible="{Binding IsEntryFocused}"
Style="{StaticResource imageClearStyle}">
<Image.GestureRecognizers>
<TapGestureRecognizer
Command="{Binding ClearCommand}"
CommandParameter="UserEmail"/>
</Image.GestureRecognizers>
</Image>
<Image
Grid.Row="1"
Grid.Column="0"
Grid.ColumnSpan="2"
Source="lineWhite.png"
Style="{StaticResource imageLineStyle}"/>
<Image
Grid.Row="1"
Grid.Column="0"
Grid.ColumnSpan="2"
Source="linePure.png"
Style="{StaticResource imageLineStyle}"
IsVisible="{Binding IsError}"/>
<Image
Grid.Row="1"
Grid.Column="0"
Grid.ColumnSpan="2"
Source="lineGradient.png"
Style="{StaticResource imageLineStyle}"
IsVisible="{Binding IsEntryFocused}"/>
<Label
Grid.Row="2"
Grid.Column="0"
Text="{Binding ErrorMessage}"
Style="{StaticResource labelErrorStyle}"
IsVisible="{Binding IsError}"/>
<Image
Grid.Row="2"
Grid.Column="1"
Source="error.png"
Style="{StaticResource imageErrorStyle}"
IsVisible="{Binding IsError}"/>
</Grid>
I would like to reuse it for example as follows:
<usercontrols:EntryControl
MainText="{Binding UserEmail}"
MainTextPlaceholder="{i18n:Translate UserEmailPlaceholder}" />
For now even this simple example is not working and I have no idea how to define Command in this control. For now I have:
public partial class EntryControl : ContentView
{
public EntryControl()
{
InitializeComponent();
}
public static readonly BindableProperty MainTextProperty =
BindableProperty.Create(
propertyName: "MainText",
returnType: typeof(string),
declaringType: typeof(string),
defaultValue: string.Empty,
defaultBindingMode: BindingMode.TwoWay);
public string MainText
{
get { return (string)this.GetValue(MainTextProperty); }
set { this.SetValue(MainTextProperty, value); }
}
public static readonly BindableProperty MainTextPlaceholderProperty =
BindableProperty.Create(
propertyName: "MainTextPlaceholder",
returnType: typeof(string),
declaringType: typeof(string),
defaultValue: string.Empty,
defaultBindingMode: BindingMode.TwoWay);
public string MainTextPlaceholder
{
get { return (string)this.GetValue(MainTextPlaceholderProperty); }
set { this.SetValue(MainTextPlaceholderProperty, value);}
}
}
Is this the right way? or is this even possible in Xamarin.Forms?
XAML:
<?xml version="1.0" encoding="utf-8" ?>
<Grid xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="ApplicationName.Controls.EntryControl"
Style="{StaticResource gridEntryStyle}">
</Grid>
xaml.cs:
namespace ApplicationName.Controls
{
public partial class EntryControl : Grid
{
public static readonly BindableProperty CommandProperty =
BindableProperty.Create(
propertyName: nameof(Command),
returnType: typeof(ICommand),
declaringType: typeof(EntryControl),
defaultValue: null,
defaultBindingMode: BindingMode.TwoWay);
public string Command
{
get { return (string)this.GetValue(CommandProperty); }
set { this.SetValue(CommandProperty, value); }
}
public EntryControl()
{
InitializeComponent();
}
}
}
using:
xmlns:controls="clr-namespace:ApplicationName.Controls;assembly=ApplicationName"
<controls:EntryLabel/>
Your issue with BindingContext
In short, you have to write down the bindings inside your control like this {Binding UserEmail, Mode=TwoWay, Source={x:Reference myControlTHIS}}, where 'myControlTHIS' is x:Name="TheCategoryHeader".
More info:
BindingContext is everything when it comes to getting things to bind and work right in an MVVM app – WPF or Xamarin. Controls inherit context from the parent control unless a different context is explicitly assigned. That’s what we need to do here. We need to tell each UI element (label, entry, button, etc.) to explicitly look at this control for its context in order to find those BindingProperties we just made. This is one of the rare occasions when we actually give a XAML element a name: When it is going to be referenced by another XAML element within the XAML itself. To the ContentView, add a tag naming the control ‘this’. That’s right. We’re going to keep to the Microsoft naming and have this item refer to itself as 'myControlTHIS'. It makes all of us comfortable and the code and markup easy to read and follow.
We can now use 'myControlTHIS' as a reference source telling the rest of our XAML where to look for properties to bind to.

Xamarin how to load image contorol if Url is an image and if video load video control

I am developing Facebook like feeds page where i have a list of Urls ( videos and images ). How can i load in xaml the Ui control specific to the Url type ( image or video ).
Example :
```<CollectionView ItemsSource="{Binding UrlList}">
<Grid>
If ( url is image)
<Image Source="{Binding Url}"/>
If ( url is video )
<MediaElement Source="{Binding Url}" />
</Grid>
</CollectionView>```
Yes, you can use DataTemplateSelector to achieve this.
A DataTemplateSelector can be used to choose a DataTemplate at runtime based on the value of a data-bound property. This enables multiple DataTemplates to be applied to the same type of object, to customize the appearance of particular objects.
1.Creating a DataTemplateSelector
A data template selector is implemented by creating a class that inherits from DataTemplateSelector. The OnSelectTemplate method is then overridden to return a particular DataTemplate.
You can refer the following code:
public class UrlTemplateSelector : DataTemplateSelector
{
public DataTemplate ImageTemplate { get; set; }
public DataTemplate VideoTemplate { get; set; }
public DataTemplate OtherTemplate { get; set; }
protected override DataTemplate OnSelectTemplate(object item, BindableObject container)
{
ItemModel model = (ItemModel)item;
if (model.Url.EndsWith(".mp4")|| model.Url.EndsWith(".avi")|| model.Url.EndsWith(".rmvb")) // you can add multiple video file suffixes
{
return VideoTemplate;
}
else if (model.Url.EndsWith(".png")|| model.Url.EndsWith(".bmp") || model.Url.EndsWith(".jpg"))//you can add multiple image file suffixes
{
return ImageTemplate;
}
else {
return OtherTemplate;
}
}
}
Suppose ItemModel is the binded item.
public class ItemModel
{
public string Name { get; set; }
public string Url { get; set; }
}
2. Usage(suppose the page is TestPage)
TestPage.xaml
<ContentPage.Resources>
<ResourceDictionary>
<DataTemplate x:Key="imageTemplate">
<ViewCell>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0.4*" />
<ColumnDefinition Width="0.6*" />
</Grid.ColumnDefinitions>
<Label Text="{Binding Name}" TextColor="Green" FontAttributes="Bold" />
<Image Grid.Column="1" Source="{Binding Url}" />
</Grid>
</ViewCell>
</DataTemplate>
<DataTemplate x:Key="videoTemplate">
<ViewCell>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0.4*" />
<ColumnDefinition Width="0.6*" />
</Grid.ColumnDefinitions>
<Label Text="{Binding Name}" TextColor="Red" FontAttributes="Bold" />
<behaviors:MediaElement Grid.Column="1" Source="{Binding Url}" />
</Grid>
</ViewCell>
</DataTemplate>
<local:UrlTemplateSelector x:Key="mediaUrlTemplateSelector" ImageTemplate="{StaticResource imageTemplate}" VideoTemplate="{StaticResource videoTemplate}" />
</ResourceDictionary>
</ContentPage.Resources>
<StackLayout Margin="20">
<Label Text="ListView with a DataTemplateSelector" FontAttributes="Bold" HorizontalOptions="Center" />
<ListView x:Name="listView" Margin="0,20,0,0" ItemTemplate="{StaticResource mediaUrlTemplateSelector}" />
</StackLayout>
For more details, you can check:https://learn.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/templates/data-templates/selector.
And there is a sample included in above document, you can try it.

ViewModel Command call from ListView.ItemTemplate in Xamarin.Forms

Here I am using MVVM architecture for developing applications. I have an image inside the listview and the listview binding with a list (ViewAcceptedList). Here I am using TapGestureRecognizer for the image. Inside the image I need to call a command (ChatTappedCommand). I am sharing my code, how I tried to achieve the requirement. I need help from an experienced one.
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:d="http://xamarin.com/schemas/2014/forms/design"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:IC="clr-namespace:ImageCircle.Forms.Plugin.Abstractions;assembly=ImageCircle.Forms.Plugin"
xmlns:Custom="clr-namespace:MTR.Customization" xmlns:pv="clr-namespace:Xamarin.Forms.PancakeView;assembly=Xamarin.Forms.PancakeView" xmlns:local="clr-namespace:MTR.Views"
mc:Ignorable="d"
x:Class="MTR.Views.MailBox.MailBoxPage"
xmlns:behaviors="clr-namespace:MTR.ViewModels.Behavior" xmlns:VM="clr-namespace:MTR.ViewModels"
BackgroundColor="#F8F0F0">
<ContentPage.BindingContext>
<VM:MailBoxPageViewModel/>
</ContentPage.BindingContext>
<ContentPage.Content>
<ListView x:Name="MailboxAcceptedList"
IsVisible="{Binding ViewAcceptedList}"
ItemsSource="{Binding MailedBoxAcceptedList}"
SeparatorColor="Transparent"
VerticalScrollBarVisibility="Never"
HasUnevenRows="True"
RelativeLayout.YConstraint="{ConstraintExpression Type=RelativeToView, ElementName=stackNavigationBar, Property=Height,Constant=2, Factor=2.9}"
RelativeLayout.HeightConstraint="{ConstraintExpression Type=RelativeToParent, Property=Height, Factor=.8}"
RelativeLayout.WidthConstraint="{ConstraintExpression Type=RelativeToParent, Property=Width, Factor=1}">
<ListView.Behaviors>
<behaviors:MailBoxListViewBehavior />
</ListView.Behaviors>
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Image x:Name="imgChat"
Source="chat_32px.png"
HeightRequest="30"
WidthRequest="30">
<Image.GestureRecognizers>
<TapGestureRecognizer BindingContext="{Binding Source={x:Reference MailBoxPage}}" Command="{Binding ChatTappedCommand}"
CommandParameter="{Binding MTRID}" />
<!--Command="{Binding Source={x:Reference Name=nameYourPage}, Path=BindingContext. EditarEnderecoCommand}" CommandParameter="{Binding CliEndCep}"
Command="{Binding ChatTappedCommand}"
CommandParameter="{Binding Source={x:Reference Item}, Path=BindingContext}"-->
</Image.GestureRecognizers>
</Image>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>`enter code here`
</ContentPage.Content>
//ViewModel:
using MTR.Models.Interface;
using MTR.Views;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Windows.Input;
using Xamarin.Forms;
namespace MTR.ViewModels
{
public class MailBoxPageViewModel : BindableObject
{
private ObservableCollection<MTR.Models.DbModel.Mail> mailedAcceptedList;
public ObservableCollection<MTR.Models.DbModel.Mail> MailedBoxAcceptedList
{
get => mailedAcceptedList;
set
{
if (value == mailedAcceptedList)
return;
mailedAcceptedList = value;
OnPropertyChanged();
}
}
public ICommand ChatTappedCommand
{
get;
private set;
}
private void ChatTapped(object obj)
{
}
public MailBoxPageViewModel()
{
ChatTappedCommand = new Command(ChatTapped);
MailedBoxAcceptedList = new ObservableCollection<Models.DbModel.Mail>();
}
}
}
Here I am trying to call a Command inside the ViewModel class and also I need to send an Id with this call. (Command, CommandParameter, BindingContext)
<TapGestureRecognizer Command="{Binding Path=BindingContext.ChatTappedCommand, Source={x:Reference Name=MailboxAcceptedList}}"
CommandParameter="{Binding}"/>

Xamarin.Forms Control Template Binding Not Working

I've specified a control template in my App.xaml:
<?xml version="1.0" encoding="utf-8"?>
<Application xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="MyApp.App">
<Application.Resources>
<ResourceDictionary>
<ControlTemplate x:Key="PageTemplate">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="50"/>
<RowDefinition Height="50"/>
<RowDefinition Height="50"/>
<RowDefinition Height="50"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<BoxView Grid.Row="0"
Grid.RowSpan="3"
BackgroundColor="#2B653E"/>
<Label Grid.Row="1"
TextColor="White"
HorizontalOptions="Center"
FontSize="36"
FontFamily="TimesNewRomanPS-BoldMT"
Text="{TemplateBinding BindingContext.HeadingText}"/>
<Image Grid.Row="2"
Grid.RowSpan="2"
Source="TGL_BG"/>
<ContentPresenter Grid.Row="4"/>
</Grid>
</ControlTemplate>
</ResourceDictionary>
</Application.Resources>
</Application>
You can see I've got one of my controls databound:
Text="{TemplateBinding BindingContext.HeadingText}"
The control template works fine, I can add it to a page without any problems, except for the bound property doesn't display:
Here is my page code:
<?xml version="1.0" encoding="UTF-8"?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MyApp.Pages.ContactPage">
<ContentView ControlTemplate="{StaticResource PageTemplate}">
<StackLayout>
<!-- Page content here, removed for brevity -->
</StackLayout>
</ContentView>
</ContentPage>
Here is my code behind:
using System;
using System.Collections.Generic;
using MyApp.ViewModels;
using Xamarin.Forms;
namespace MyApp.Pages
{
public partial class ContactPage : ContentPage
{
public ContactPage(ContactPageViewModel viewModel)
{
InitializeComponent();
viewModel.Navigation = Navigation;
BindingContext = viewModel;
}
}
}
Here you can see I'm setting the binding context to the ViewModel (which works for everything outside the template). And here is my ViewModel:
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;
using MyApp.Helpers;
using Xamarin.Forms;
namespace MyApp.ViewModels
{
public class ContactPageViewModel : ViewModel
{
public string HeadingText = "Contact Us";
//Other properties and commands here, removed for brevity
}
}
As you can see I've got a public property here called 'HeadingText' which is what I'm binding to in the view.
I've read the documentation and a few examples/tutorials. According to what I can see this should work. Can anyone see what's wrong with this?
EDIT:
I've now got this working. In my ViewModel, I changed this:
public string HeadingText = "Contact Us";
to this:
public string HeadingText
{
get
{
return "Contact Us";
}
}
Leaving the question open now as hoping someone can provide an explanation.
binding only works with public properties
// this is a field, not a property
public string HeadingText = "Contact Us";
// this is a property
public string HeadingText
{
get
{
return "Contact Us";
}
}

Datagrid not showing data even though its boudn

I have a problem with my MVVM Light implementation where I have my WPF Toolkit DataGrid and Data context bound to the correct object but no data is showing up. Can someone tell me what I'm doing wrong?
Here is my code:
MainViewModel.cs
public class MainViewModel : ViewModelBase
{
private static Logger logger = LogManager.GetCurrentClassLogger();
private C.Wsi.ClientSession privateSession;
private ObservableCollection<CashAccount> _cashaccounts;
public ObservableCollection<CashAccount> CashAccounts
{
get { return _cashaccounts; }
set
{
if (_cashaccounts.Equals(value))
{
return;
}
_cashaccounts = value;
RaisePropertyChanged("CashAccounts");
}
}
/// <summary>
/// Initializes a new instance of the MainViewModel class.
/// </summary>
public MainViewModel()
{
if (IsInDesignMode)
{
// Code runs in Blend --> create design time data.
}
else
{
_cashaccounts = new ObservableCollection<CashAccount>();
// Subscribe to CollectionChanged event
_cashaccounts.CollectionChanged += OnCashAccountListChanged;
logger.Info("----- Start -----");
// Code runs "for real"
Cs.Helper.Session session = new Session();
privateSession = session.getSession();
logger.Info("Private Session: " + privateSession.GetHashCode());
logger.Info("...Connected.....");
Cs.Helper.ResultSet results = new ResultSet();
PositionBean[] pos = results.getPositions(privateSession);
logger.Info("Positions returned: " + pos.Length);
SecurityBean[] secs = results.getSecurities(privateSession);
logger.Info("Securities returned: " + secs.Length);
ArrayBuilder ab = new ArrayBuilder(pos, secs);
CashAccount c = new CashAccount();
c.qtySod = 100.00;
c.name = "Hi";
c.account = "Acct1";
c.cashAmount = 67.00;
_cashaccounts.Add(c);
RaisePropertyChanged("CashAccounts");
//this._cashaccounts=ab.joinPositionSecurities();
}
}
void OnCashAccountListChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
}
////public override void Cleanup()
////{
//// // Clean up if needed
//// base.Cleanup();
////}
}
MainWindow.xaml
<Window x:Class="CreditSuisse.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:CreditSuisse.Helper"
xmlns:dg="http://schemas.microsoft.com/wpf/2008/toolkit"
mc:Ignorable="d"
Height="301"
Width="520"
Title="Credit Suisse - Custodial Cash Application"
DataContext="{Binding Path=Main, Source={StaticResource Locator}}">
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Skins/MainSkin.xaml" />
</ResourceDictionary.MergedDictionaries>
<local:VisibilityConverter x:Key="VisibilityConverter" />
<!-- DataGrid Background -->
<LinearGradientBrush x:Key="BlueLightGradientBrush" StartPoint="0,0" EndPoint="0,1">
<GradientStop Offset="0" Color="#FFEAF3FF"/>
<GradientStop Offset="0.654" Color="#FFC0DEFF"/>
<GradientStop Offset="1" Color="#FFC0D9FB"/>
</LinearGradientBrush>
<!-- DatGrid style -->
<Style TargetType="{x:Type dg:DataGrid}">
<Setter Property="Margin" Value="5" />
<Setter Property="Background" Value="{StaticResource BlueLightGradientBrush}" />
<Setter Property="BorderBrush" Value="#FFA6CCF2" />
<Setter Property="RowBackground" Value="White" />
<Setter Property="AlternatingRowBackground" Value="#FDFFD0" />
<Setter Property="HorizontalGridLinesBrush" Value="Transparent" />
<Setter Property="VerticalGridLinesBrush" Value="#FFD3D0" />
<Setter Property="RowHeaderWidth" Value="0" />
</Style>
<!-- Enable rows as drop targets -->
<Style TargetType="{x:Type dg:DataGridRow}">
<Setter Property="AllowDrop" Value="True" />
</Style>
</ResourceDictionary>
</Window.Resources>
<dg:DataGrid DataContext="{Binding MainViewModel}" ItemsSource="{Binding CashAccounts}">
Margin="5" AutoGenerateColumns="True" HorizontalScrollBarVisibility="False">
<dg:DataGrid.Columns>
<dg:DataGridTextColumn Binding="{Binding account}" Header="Account Code" />
<dg:DataGridTextColumn Binding="{Binding name}" Header="Security Name" />
<dg:DataGridTextColumn Binding="{Binding cashAmount}" Header="Quantity Start of Day" />
<dg:DataGridTextColumn Binding="{Binding price}" Header="Cash Delta (Price Delta)" />
<dg:DataGridTemplateColumn Header="Action">
<dg:DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Button Content="Get" Visibility="{Binding cashChanged, Converter={StaticResource VisibilityConverter}}" Background="Red" />
</DataTemplate>
</dg:DataGridTemplateColumn.CellTemplate>
</dg:DataGridTemplateColumn>
</dg:DataGrid.Columns>
</dg:DataGrid>
When you do DataContext="{Binding Path=Main, Source={StaticResource Locator}}" in your Window and after DataContext="{Binding MainViewModel}" in the Datagrid, WPF tries to bind to a property named MainViewModel on your MainViewModel class which will fail. You can confirm this by looking for the binding error in the Output window in VS.
Just remove DataContext="{Binding MainViewModel}" from the DataGrid and it should work.
EDIT:
There is an extra closing > at the end of the first line in your XAML:
<dg:DataGrid DataContext="{Binding MainViewModel}" ItemsSource="{Binding CashAccounts}">
Margin="5" AutoGenerateColumns="True" HorizontalScrollBarVisibility="False">
It should be:
<dg:DataGrid DataContext="{Binding MainViewModel}" ItemsSource="{Binding CashAccounts}"
Margin="5" AutoGenerateColumns="True" HorizontalScrollBarVisibility="Disabled">
Note: False is not a valid value for HorizontalScrollBarVisibility it supports Auto, Disabled, Hidden, Visible
But I don't know why WPF throws Operation is not valid while ItemsSource is in use. Access and modify elements with ItemsControl.ItemsSource instead for your original XAML instead of some more meaningful error.