I have just started to learn Xaml, and currently building a app to control data from SQL vith MVVM architecture. I have been working on to open a new page by using a DataGrid.SelectionChanged event for 2 days. However, when I try to write xaml as below I get the error :
'System.Windows.Markup.XamlParseException: 'A 'Binding' cannot be set on the 'AddSourceUpdatedHandler' property of type 'BeginStoryboard'. A 'Binding' can only be set on a DependencyProperty of a DependencyObject.'
You can see I can open the CustomerView from OperationsView by using the command of RadioButton, perfectly.
I would appreciate for your any help.
My xaml is below:
<UserControl x:Class="Tourism.MainPage.MVVM.View.OperationsView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Tourism.MainPage.MVVM.View"
xmlns:viewModel="clr-namespace:Tourism.MainPage.MVVM.ViewModel"
mc:Ignorable="d"
d:DesignHeight="800"
d:DesignWidth="2000"
Background="#24292f">
<StackPanel>
<DataGrid x:Name="dgwOperationMain"
HorizontalAlignment="Left"
Margin="50,50,0,0"
Width="700"
Height="425"
IsReadOnly="True"
Loaded="dgwOperationMain_Loaded"
AutoGenerateColumns="False"
FontFamily="/Fonts/#Poppins"
ScrollViewer.CanContentScroll="False"
SelectionChanged="dgwOperationMain_SelectionChanged">
<DataGrid.Triggers>
<EventTrigger RoutedEvent="DataGrid.SelectionChanged">
<EventTrigger.Actions>
<BeginStoryboard Binding.SourceUpdated="{Binding Path= CustomerViewCommand}">
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
</DataGrid.Triggers>
<DataGrid.Columns>
<DataGridTextColumn Header="DocumentCode"
MinWidth="120"
Binding="{Binding DocumentCode}" />
<DataGridTextColumn Header="Operator"
MinWidth="50"
Binding="{Binding Operator}" />
<DataGridTextColumn Header="StartDate"
MinWidth="70"
Binding="{Binding StartDate}" />
<DataGridTextColumn Header="EndDate"
MinWidth="70"
Binding="{Binding EndDate}" />
<DataGridTextColumn Header="Pax"
MinWidth="20"
Binding="{Binding Pax}" />
<DataGridTextColumn Header="Room"
MinWidth="20"
Binding="{Binding Room}" />
<DataGridTextColumn Header="Currency"
MinWidth="30"
Binding="{Binding Currency}" />
</DataGrid.Columns>
</DataGrid>
<DataGrid x:Name="dgwCustomerOperation"
HorizontalAlignment="Left"
Margin="790,-425,0,0"
Width="752"
Height="425"
IsReadOnly="True"
AutoGenerateColumns="True"
FontFamily="/Fonts/#Poppins" />
<RadioButton Content="Customers"
HorizontalContentAlignment="Left"
x:Name="btnCustomer"
Foreground="White"
Background="YellowGreen"
FontFamily="/Fonts/#Poppins"
HorizontalAlignment="Left"
Height="50"
Width="180"
Margin="500,0,0,0"
Style="{StaticResource MenuButtonTheme}"
Command="{Binding Path= CustomerViewCommand}"
Checked="btnCustomer_Checked" />
<ContentControl Margin="0,0,0,0"
Content="{Binding CurrentView}" />
</StackPanel>
</UserControl>
This part of the code is giving me the error:
<BeginStoryboard Binding.SourceUpdated="{Binding Path= CustomerViewCommand}">
My ObservableObject:
public class ObservableObject : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string name = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
}
Relay Command;
public class RelayCommand : ICommand
{
private Action<object> _execute;
private Predicate<object> _canExecute;
public event EventHandler CanExecuteChanged
{
add { CommandManager.RequerySuggested += value; }
remove { CommandManager.RequerySuggested -= value; }
}
public RelayCommand(Action<object> execute, /* Func<object,bool>*/Predicate<object> canExecute /*= null*/ )
{
_execute = execute;
_canExecute = canExecute;
}
public bool CanExecute( object parameter )
{
return /*_canExecute == null || */_canExecute(parameter);
}
public void Execute( object parameter )
{
_execute(parameter);
}
}
ViewModel;
public abstract class ViewModel :ObservableObject{}
MainViewModel;
public class MainViewModel : Core.ViewModel
{
public RelayCommand HomeViewCommand { get; set; }
public RelayCommand OpeartionViewCommand { get; set; }
public RelayCommand CustomerViewCommand { get; set; }
public RelayCommand SettingsViewCommand { get; set; }
private object _currentView;
public object CurrentView
{
get { return _currentView; }
set
{
_currentView = value;
OnPropertyChanged();
}
}
private INavigationService _navigation;
public INavigationService Navigation
{
get => _navigation;
set
{
_navigation = value;
OnPropertyChanged();
}
}
public MainViewModel(INavigationService navService)
{
Navigation = navService;
Navigation.NavigateTo<HomeViewModel>();
HomeViewCommand = new RelayCommand(o => { Navigation.NavigateTo<HomeViewModel>(); }, canExecute: o => true);
OpeartionViewCommand = new RelayCommand(o => { Navigation.NavigateTo<OperationViewModel>(); }, canExecute: o => true);
CustomerViewCommand = new RelayCommand(o => { Navigation.NavigateTo<CustomerViewModel>(); }, canExecute: o => true);
SettingsViewCommand = new RelayCommand(o => { Navigation.NavigateTo<SettingsViewModel>(); }, canExecute: o => true);
}
}
OperationViewModel;
public class OperationViewModel : Core.ViewModel
{
private INavigationService _navigation;
public INavigationService Navigation
{
get => _navigation;
set
{
_navigation = value;
OnPropertyChanged();
}
}
public RelayCommand CustomerViewCommand { get; set; }
public OperationViewModel(INavigationService navigation)
{
Navigation = navigation;
CustomerViewCommand = new RelayCommand(o => { Navigation.NavigateTo<CustomerViewModel>(); }, canExecute: o => true);
}
}
CustomerViewModel;
public class CustomerViewModel : Core.ViewModel
{
private INavigationService _navigation;
public INavigationService Navigation
{
get => _navigation;
set
{
_navigation = value;
OnPropertyChanged();
}
}
public RelayCommand OpeartionViewCommand { get; set; }
public CustomerViewModel(INavigationService navigation)
{
Navigation = navigation;
OpeartionViewCommand = new RelayCommand(o => { Navigation.NavigateTo<OperationViewModel>(); }, canExecute: o/*: object*/ => true);
}
}
Navigation Service;
public interface INavigationService
{
ViewModel CurrentView { get; }
void NavigateTo<T>() where T : ViewModel;
}
public class NavigationService : ObservableObject, INavigationService
{
private readonly Func<Type, ViewModel> _viewModelFactory;
public ViewModel _currentView;
public ViewModel CurrentView
{
get => _currentView;
private set
{
_currentView = value;
OnPropertyChanged();
}
}
public NavigationService(Func<Type,ViewModel> viewModelFactory)
{
_viewModelFactory = viewModelFactory;
}
public void NavigateTo<TViewModel>() where TViewModel : ViewModel
{
ViewModel viewModel =_viewModelFactory.Invoke(typeof(TViewModel));
CurrentView = viewModel;
}
}
App.xaml.cs;
public partial class App : Application
{
private readonly ServiceProvider _serviceProvider;
public App()
{
IServiceCollection services = new ServiceCollection(); //specifying the DI Container
services.AddSingleton<MainWindow>(provider => new MainWindow
{
DataContext = provider.GetRequiredService<MainViewModel>()
});
services.AddSingleton<MainViewModel>();
services.AddSingleton<OperationViewModel>();
services.AddSingleton<HomeViewModel>();
services.AddSingleton<CustomerViewModel>();
services.AddSingleton<SettingsViewModel>();
services.AddSingleton<INavigationService, Services.NavigationService>();
services.AddSingleton<Func<Type, ViewModel>>(serviceProvider => viewModelType => (ViewModel)serviceProvider.GetRequiredService(viewModelType));
_serviceProvider = services.BuildServiceProvider();
}
protected override void OnStartup(StartupEventArgs e)
{
var mainWindow = _serviceProvider.GetRequiredService<MainWindow>();
mainWindow.Show();
base.OnStartup(e);
}
}
App.xaml;
<Application x:Class="Tourism.MainPage.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:Tourism.MainPage"
xmlns:viewModel="clr-namespace:Tourism.MainPage.MVVM.ViewModel"
xmlns:view="clr-namespace:Tourism.MainPage.MVVM.View"
xmlns:theme="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Aero2">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Theme/MenuButtonTheme.xaml" />
<ResourceDictionary Source="Theme/TextBoxTheme.xaml" />
</ResourceDictionary.MergedDictionaries>
<DataTemplate DataType="{x:Type viewModel:HomeViewModel}">
<view:HomeView />
</DataTemplate>
<DataTemplate DataType="{x:Type viewModel:OperationViewModel}">
<view:OperationsView />
</DataTemplate>
<DataTemplate DataType="{x:Type viewModel:CustomerViewModel}">
<view:CustomerView />
</DataTemplate>
<DataTemplate DataType="{x:Type viewModel:SettingsViewModel}">
<view:SettingsView />
</DataTemplate>
</ResourceDictionary>
</Application.Resources>
</Application>