I am trying to make a small program mainly to learn MVVM. Its a small Book Library.
I have 4 views(and 4 viewmodels).
MainWindow is the parent view, where i display the other 3 view in a content control.
The other 3 child views are HomeView, BookManagingView, ReaderManagingView.
In HomeView, i display 2 ListViews(one with readers, one with books), and in the other 2 views i edit/add books or readers.
In my HomeView i also have 2 buttons. When i click the buttons i want to switch from the HomeView, to BookManagingView or ReaderManagingView.
If i am trying to switch to any of the Views from the MainWindow, it works.
What i am trying to do is to switch from the HomeView, to BookManagingView or ReaderManagingView. How can i achieve that?
MainWindow:
<Grid>
<ContentControl Content="{Binding CurrentView}" Height="340" Width="500" />
<Button x:Name="btnHomeView" Content="Home" Command="{Binding ChangeViewToHomeView, UpdateSourceTrigger=PropertyChanged}" HorizontalAlignment="Left" Margin="16,70,0,0" VerticalAlignment="Top" Width="75"/>
<Button x:Name="btnBookManagingView" Content="Reader Options" Command="{Binding ChangeViewToReaderManagView,UpdateSourceTrigger=PropertyChanged}" HorizontalAlignment="Left" Margin="96,70,0,0" VerticalAlignment="Top" Width="92"/>
<Button x:Name="btnReaderManagingView" Content="Books Options" Command="{Binding ChangeViewToBookManagView,UpdateSourceTrigger=PropertyChanged}" HorizontalAlignment="Left" Margin="193,70,0,0" VerticalAlignment="Top" Width="92"/>
</Grid>
MainWindowVM:
public class MainWindowViewModel : ViewModelBase
{
private object currentView;
private HomeViewModel homeVM;
private ReaderManagingViewModel readerManagingVM;
private BookManagingViewModel bookManagingVM;
public MainWindowViewModel()
{
homeVM = new HomeViewModel();
readerManagingVM = new ReaderManagingViewModel();
bookManagingVM = new BookManagingViewModel();
CurrentView = homeVM;
ChangeViewToHomeView = new DefCommand(DisplayHomeView);
ChangeViewToReaderManagView = new DefCommand(DisplayReaderManagingView);
ChangeViewToBookManagView = new DefCommand(DisplayBookManagingView);
}
public DefCommand ChangeViewToHomeView { get; private set; }
public DefCommand ChangeViewToReaderManagView { get; private set; }
public DefCommand ChangeViewToBookManagView { get; private set; }
public object CurrentView
{
get { return currentView; }
set { currentView = value; RaisePropertyChanged(); }
}
public void DisplayHomeView()
{
CurrentView = homeVM;
}
public void DisplayReaderManagingView()
{
CurrentView = readerManagingVM;
}
public void DisplayBookManagingView()
{
CurrentView = bookManagingVM;
}
HomeView:
<Grid>
<ListView x:Name="listviewReaders" ItemsSource="{Binding ReadersList}" SelectedItem="{Binding SelectedReader, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Width="160" Margin="25,23,315,40">
...
<ListView x:Name="listviewBooks" ItemsSource="{Binding BookList, Mode=OneWay}" SelectedItem="{Binding SelectedBook, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Width="160" Margin="316,50,24,117">
...
<Button x:Name="btnEditReader" Command="{Binding EditReaderSwitch, UpdateSourceTrigger=PropertyChanged}" Content="EditR" HorizontalAlignment="Left" Margin="316,305,0,0" VerticalAlignment="Top" Width="74"/>
<Button x:Name="btnEditBook" Command="{Binding EditBookSwitch, UpdateSourceTrigger=PropertyChanged}" Content="EditB" HorizontalAlignment="Left" Margin="402,305,0,0" VerticalAlignment="Top" Width="74"/>
</Grid>
HomeVM:
private Reader selectedReader;
private Book selectedBook;
private BookListFilter selectedFilter;
private ObservableCollection<Book> bookList;
private ObservableCollection<Reader> readerList;
private IEnumerable<BookListFilter> bookLstItemSrc;
public HomeViewModel()
{
SelectedReader = new Reader();
SelectedBook = new Book();
SelectedFilter = BookListFilter.AllBooks;
BookDBDataContext rdb = new BookDBDataContext();
ReadersList = new ObservableCollection<Reader>(rdb.Readers);
GetBookList();
EditReaderSwitch = new DefCommand(EditReaderInfo);
EditBookSwitch = new DefCommand(EditBookInfo);
}
public DefCommand EditReaderSwitch { get; private set; }
public DefCommand EditBookSwitch { get; private set; }
private void EditBookInfo()
{
var tmpBook = new BookManagingViewModel(this);
var tmpMwvm = new MainWindowViewModel();
tmpMwvm.DisplayBookManagingView();
}
private void EditReaderInfo()
{
var tmpReader = new ReaderManagingViewModel(this);
var tmpMwvm = new MainWindowViewModel();
tmpMwvm.DisplayReaderManagingView();
}
Book & Reader ManagingViews have a bunch of textboxes and buttons for adding, deleting to/from database.
Book & Reader ManagingVM have methods for adding/deleting to/from database(right now they are empty and i will finish them if i manage to solve this problem first)
I have tried to navigate from HomeView to Book/ReaderManagingView with the EditBook/ReaderSwitch commands and EditBook/ReaderInfo() methods, but it doesnt work.
What am i doing wrong, and what should i do to fix it?
Sorry for the long post.
You need to set the CurrentView property of the existing MainWindowViewModel instance. Right now you are creating a new instance of the class.
You could inject the HomeViewModel with a MainWindowViewModel:
private readonly MainWindowViewModel _x;
public HomeViewModel(MainWindowViewModel x)
{
_x = x;
SelectedReader = new Reader();
...
}
private void EditBookInfo()
{
_x.DisplayBookManagingView();
}
MainWindowViewModel:
public MainWindowViewModel()
{
homeVM = new HomeViewModel(this);
}
Related
I have a ViewModel with all the properties that i will need in every sub ViewModel.
It's the first time i try to split commands and viewmodel to multiple files. Last time everything was in the same ViewModel and it was a pain to work with it. Everything shows up as expected but i want to find a way to pass the same data in every viewmodel.
From my GetOrdersCommand, i want to get the HeaderViewModel.SelectedSource property. I didn't find any way to do it without getting a null return or loosing the property data...
I would like to call my GetOrdersCommand from HeaderView button too.
Any tips how i can achieve this ? Perhaps, my design is not good for what i'm trying to do ?
MainWindow.xaml
<views:HeaderView Grid.Row="0" Grid.Column="1" Grid.ColumnSpan="2" DataContext="{Binding HeaderViewModel}" LoadHeaderViewCommand="{Binding LoadHeaderViewCommand}"/>
<TabControl TabStripPlacement="Bottom" Grid.Row="1" Grid.Column="1" Grid.RowSpan="2" Grid.ColumnSpan="2">
<TabItem Header="General">
</TabItem>
<TabItem Header="Orders">
<views:OrderView DataContext="{Binding OrderViewModel}" GetOrdersCommand="{Binding GetOrdersCommand}"/>
</TabItem>
</TabControl>
HeaderView.xaml
<DockPanel>
<ComboBox DockPanel.Dock="Left" Width="120" Margin="4" VerticalContentAlignment="Center" ItemsSource="{Binding SourceList}" SelectedItem="{Binding SelectedSource}" DisplayMemberPath="SourceName"/>
<Button x:Name="btnTest" HorizontalAlignment="Left" DockPanel.Dock="Left" Margin="4" Content="Test"/>
</DockPanel>
HeaderView.xaml.cs
public partial class OrderView : UserControl
{
public ICommand GetOrdersCommand
{
get { return (ICommand)GetValue(GetOrdersCommandProperty); }
set { SetValue(GetOrdersCommandProperty, value); }
}
public static readonly DependencyProperty GetOrdersCommandProperty =
DependencyProperty.Register("GetOrdersCommand", typeof(ICommand), typeof(OrderView), new PropertyMetadata(null));
public OrderView()
{
InitializeComponent();
}
private void UserControl_Loaded(object sender, RoutedEventArgs e)
{
if (GetOrdersCommand != null)
{
GetOrdersCommand.Execute(this);
}
}
}
MainViewModel.cs
private OrderViewModel orderViewModel;
public OrderViewModel OrderViewModel { get; set; } // Getter, setter with OnPropertyChanged
private HeaderViewModel headerViewModel;
public HeaderViewModel HeaderViewModel { get; set; } // Getter, setter with OnPropertyChanged
public MainViewModel()
{
HeaderViewModel = new HeaderViewModel();
OrderViewModel = new OrderViewModel();
}
HeaderViewModel.cs
public ICommand LoadHeaderViewCommand { get; set; }
public HeaderViewModel()
{
LoadHeaderViewCommand = new LoadHeaderViewCommand(this);
}
GetOrdersCommand.cs
public class GetOrdersCommand : ICommand
{
public event EventHandler CanExecuteChanged;
private readonly OrderViewModel _orderViewModel;
public GetOrdersCommand(OrderViewModel orderViewModel)
{
_orderViewModel = orderViewModel;
}
public bool CanExecute(object parameter)
{
return true;
}
public void Execute(object parameter)
{
/* Build Order List according to HeaderViewModel.SelectedSource */
_orderViewModel.Orders = new ObservableCollection<Order>()
{
new Order { ID = 1, IsReleased = false, Name = "Test1"},
new Order { ID = 2, IsReleased = true, Name = "Test2"},
};
}
}
Thanks guys ! I moved my commands to their owning ViewModel as suggested.
I tried MVVVM Light Tools and found about Messenger Class.
I used it to send my SelectedSource (Combobox from HeaderView) from HeaderViewModel to OrderViewModel. Am i suppose to use Messenger class like that ? I don't know, but it did the trick!!!
I thought about moving GetOrdersCommand to OrderViewModel, binding my button command to OrderViewModel, binding SelectedSource as CommandParameter but i didn't know how i was suppose to RaiseCanExecuteChanged when HeaderViewModel.SelectedSource changed... Any advice?
MainWindow.xaml
<views:HeaderView DataContext="{Binding Source={StaticResource Locator}, Path=HeaderVM}" Grid.Row="0" Grid.Column="1" Grid.ColumnSpan="2"/>
<TabControl TabStripPlacement="Bottom" Grid.Row="1" Grid.Column="1" Grid.RowSpan="2" Grid.ColumnSpan="2">
<TabItem Header="General">
</TabItem>
<TabItem Header="Orders">
<views:OrderView DataContext="{Binding Source={StaticResource Locator}, Path=OrderVM}"/>
</TabItem>
</TabControl>
OrderViewModel.cs
private ObservableCollection<Order> _orders;
public ObservableCollection<Order> Orders
{
get { return _orders; }
set
{
if (_orders != value)
{
_orders = value;
RaisePropertyChanged(nameof(Orders));
}
}
}
public OrderViewModel()
{
Messenger.Default.Register<Source>(this, source => GetOrders(source));
}
private void GetOrders(Source source)
{
if (source.SourceName == "Production")
{
Orders = new ObservableCollection<Order>(){
new Order { ID = 1, IsReleased = false, Name = "Production 1" }
};
}
else
{
Orders = new ObservableCollection<Order>(){
new Order { ID = 2, IsReleased = true, Name = "Test 1" }
};
}
}
Part of HeaderViewModel.cs
private Source _SelectedSource;
public Source SelectedSource
{
get { return _SelectedSource; }
set
{
if (_SelectedSource != value)
{
_SelectedSource = value;
RaisePropertyChanged(nameof(SelectedSource));
GetOrdersCommand.RaiseCanExecuteChanged();
}
}
}
private RelayCommand _GetOrdersCommand;
public RelayCommand GetOrdersCommand
{
get
{
if (_GetOrdersCommand == null)
{
_GetOrdersCommand = new RelayCommand(GetOrders_Execute, GetOrders_CanExecute);
}
return _GetOrdersCommand;
}
}
private void GetOrders_Execute()
{
Messenger.Default.Send(SelectedSource);
}
private bool GetOrders_CanExecute()
{
return SelectedSource != null ? true : false;
}
If I have an ObservableCollection in one of my classes. In my code behind my view I have an object of this class and use it as the DataBinding
this.DataContext = MyCustomClass;
in the xaml code of the view I want to bind several buttons to items in the Observable collection. Something like this:
<Button x:Name="Bid_Price_10" Grid.Row="0" Content="{Binding myObservableCollection[0].Price, Mode=OneWay}" Grid.ColumnSpan="2" HorizontalAlignment="Stretch" UseLayoutRounding="True" Padding="0"/>
<Button x:Name="Bid_Price_11" Grid.Row="1" Content="{Binding myObservableCollection[1].Price, Mode=OneWay}" Grid.ColumnSpan="2" HorizontalAlignment="Stretch" UseLayoutRounding="True" Padding="0"/>
At the moment this is not working, am I missing something ?
EDIT: Create full code to demo what I am trying to do:
So I have a Coffee class:
class Coffee
{
public int price { get; set; }
}
I have a drinks class that holds a list of coffees:
class Drinks
{
public List<Coffee> CoffeeList;
public Drinks()
{
CoffeeList = new List<Coffee>();
for (int i = 0; i < 10; i++)
{
Coffee c = new Coffee();
c.price = i;
CoffeeList.Add(c);
}
this.startCoffeePriceUpdateThread();
}
private void UpdateCofffeePrice()
{
while (true)
{
Thread.Sleep(1000);
foreach (var c in CoffeeList)
{
c.price++;
}
}
}
public void startCoffeePriceUpdateThread()
{
Thread coffeeThread = new Thread(new ThreadStart(UpdateCofffeePrice));
coffeeThread.Start();
}
}
my main window code behind:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
Drinks ourDrinks = new Drinks();
this.DataContext = ourDrinks;
}
}
and my xaml code:
<Grid x:Name="Grid" HorizontalAlignment="Left" Height="193" Margin="77,31,0,0" VerticalAlignment="Top" Width="315">
<Button x:Name="Button" Content="{Binding CoffeeList[0].Price}" HorizontalAlignment="Left" Margin="49,25,0,0" VerticalAlignment="Top" Width="75" Height="28"/>
</Grid>
So the problem is that I am not seeing anything in the button. At the moment I am not using INotifyPropertyChange as I have been advised it would not be needed.
As Clemens suggested: if everything is fixed, you won't need ObservableCollection nor PropertyChanged notification. The following code should be sufficient:
public class Stuff
{
public string Price { get; set; }
}
public class myCustomClass
{
public List<Stuff> myCollection { get; set; }
}
public partial class MainWindow : Window
{
public myCustomClass myCustomInstance = new myCustomClass();
public MainWindow()
{
InitializeComponent();
myCustomInstance.myCollection = new List<Stuff>();
myCustomInstance.myCollection.Add(new Stuff() { Price = "1200$" });
myCustomInstance.myCollection.Add(new Stuff() { Price = "5.5$" });
this.DataContext = myCustomInstance;
}
}
And the simplified XAML
<Button Content="{Binding myCollection[0].Price, Mode=OneWay}"/>
<Button Content="{Binding myCollection[1].Price, Mode=OneWay}" />
NB: I specified an instance of myCustomClass as the DataContext. If you really need to bind it to the class, let me know and I will update the code.
I have a ListBox I want to fill with data from two TextBoxesby clicking a Button. I think the problem comes from the differents textblock i have in my listbox. Here is what i want in image :
TheUI
The MainWindow.xaml of my listbox :
<ListBox x:Name="listBox"
ItemsSource="{Binding Issues}" Grid.Column="1" HorizontalAlignment="Left" Height="366" VerticalAlignment="Top" Width="453" Margin="0,0,-1,0">
<StackPanel Margin="3">
<DockPanel >
<TextBlock FontWeight="Bold" Text="Issue:"
DockPanel.Dock="Left"
Margin="5,0,10,0"/>
<TextBlock Text=" " />
<TextBlock Text="{Binding Issue}" Foreground="Green" FontWeight="Bold" />
</DockPanel>
<DockPanel >
<TextBlock FontWeight="Bold" Text="Comment:" Foreground ="DarkOrange"
DockPanel.Dock="Left"
Margin="5,0,5,0"/>
<TextBlock Text="{Binding Comment}" />
</DockPanel>
</StackPanel>
</ListBox>
My MainWindow.xaml.cs
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
public sealed class ViewModel
{
public ObservableCollection<Issue> Issues { get; private set; }
public ViewModel()
{
Issues = new ObservableCollection<Issue>();
}
}
private void addIssue_Click(object sender, RoutedEventArgs e)
{
var vm = new ViewModel();
vm.Issues.Add(new Issue { Name = "Jon Skeet", Comment = "lolilol" });
DataContext = vm;
InitializeComponent();
}
}
My Issue.cs :
public sealed class Issue
{
public string Name { get; set; }
public string Comment { get; set; }
}
I follow this tutorial but i don't want to implement a Database :
Tuto
I also try to use this stackoverflow question
The error i have is 'System.InvalidOperationException' The Items collection must be empty to use ItemsSource
But not sure this is the heart of the problem.
Remove whatever you have inserted between <ListBox> and </ListBox>, as it is treated as part of Items collection.
Instead shift that content between <ListBox.ItemTemplate>...</ListBox.ItemTemplate>.
You don't need to update Context and InitializeComponent every time, atleast to your case.
public partial class MainWindow : Window
{
ViewModel vm = new ViewModel();
public MainWindow()
{
InitializeComponent();
DataContext = vm;
}
public sealed class ViewModel
{
public ObservableCollection<Issue> Issues { get; private set; }
public ViewModel()
{
Issues = new ObservableCollection<Issue>();
}
}
private void addIssue_Click(object sender, RoutedEventArgs e)
{
vm.Issues.Add(new Issue { Name = "Jon Skeet", Comment = "lolilol" });
}
}
When I click to register button (for example) in RegistrationViewModel or any other ViewModel, I would like to change the LeftSlide and MainSlide properties in MainWindowViewModel
LeftSlide = _leftSlides[0];
MainSlide = any other ViewModel;
I've read this documentation, but i can't implement this in my code
https://catelproject.atlassian.net/wiki/display/CTL/MVVM+communication+styles
How can i do this? Help me please
MainWindow.xaml
<DockPanel LastChildFill="True">
<DockPanel DockPanel.Dock="Top">
<Grid Width="120" DockPanel.Dock="Left">
<ContentControl Content="{Binding LeftSlide,
Converter={StaticResource ViewModelToViewConverter}}"></ContentControl>
</Grid>
<Grid DockPanel.Dock="Right">
<ContentControl Content="{Binding MainSlide,
Converter={StaticResource ViewModelToViewConverter}}"></ContentControl>
</Grid>
</DockPanel>
</DockPanel>
RegistrationViewModel.cs
public class RegistrationViewModel : ViewModelBase
{
public RegistrationViewModel()
{
RegistrationUserCommand = new Command(OnRegistrationUserCommandExecute);
}
public Command RegistrationUserCommand { get; private set; }
private void OnRegistrationUserCommandExecute()
{
//when I click this button, I need to change LeftSlide property in
// MainWindowViewModel to _leftSlides[1] (LeftSlide = _leftSlides[1];)
//for example
}
}
MainWindowViewModel.cs
public class MainWindowViewModel : ViewModelBase
{
private List<IViewModel> _leftSlides;
private List<IViewModel> _mainSlides;
public MainWindowViewModel()
{
_leftSlides = new List<IViewModel>
{
new NavViewModel(),
new AnotherNavViewModel()
//another ViewModels
};
_mainSlides = new List<IViewModel>
{
new RegistrationViewModel()
//another ViewModels
};
//Default ViewModels
MainSlide = _mainSlides[0];
LeftSlide = _leftSlides[0];
}
public IViewModel LeftSlide { get; set; }
public IViewModel MainSlide { get; set; }
}
I haven't any experience with WPF and Catel. It's our first project with my team. We are studying. And we can't stop using Catel Framework.
I have a simple MVVM project I am learning on. I am trying to add to an ObservableCollection through an ICommand command, but I am unable to?
MainWindow.cs I haven't added anything*
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:Local="clr-namespace:WpfApplication1"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Grid.DataContext>
<Local:ViewModel></Local:ViewModel>
</Grid.DataContext>
<ListView Grid.Row="0" x:Name="lstNames" Margin="5,5,5,5" Grid.Column="1" ItemsSource="{Binding View_}">
<ListView.View>
<GridView x:Name="Setting_Items">
<GridViewColumn Header="Setting_A" DisplayMemberBinding="{Binding View_String}"/>
</GridView>
</ListView.View>
</ListView>
<TextBox Height="23"
HorizontalAlignment="Left"
Margin="145,195,0,0"
Name="textBox1"
VerticalAlignment="Top"
Width="120" />
<ComboBox Height="23"
HorizontalAlignment="Left"
Margin="269,195,0,0"
Name="My_ComboBox"
VerticalAlignment="Top"
Width="222"
ItemsSource="{Binding View_}"/>
<Button Content="Message Text"
Height="23"
HorizontalAlignment="Left"
Margin="52,166,0,0"
Name="button1"
VerticalAlignment="Top"
Width="75"
CommandParameter="{Binding Text, ElementName=textBox1}"
Command="{Binding Print_Line}"/>
<Button Content="Add To Drop"
Height="23"
HorizontalAlignment="Left"
Margin="52,195,0,0"
Name="button2"
VerticalAlignment="Top"
Width="75"
/>
</Grid>
public class View
{
public string View_String {get; set;}
}
public class SimpleDelegateCommand : ICommand
{
Action<object> _executeDelegate;
public SimpleDelegateCommand(Action<object> executeDelegate)
{
_executeDelegate = executeDelegate;
}
public void Execute(object parameter)
{
_executeDelegate(parameter);
}
public bool CanExecute(object parameter) { return true; }
public event EventHandler CanExecuteChanged;
}
public class ViewModel
{
private ObservableCollection<View> _View;
public string _View_String { get; set; }
public ObservableCollection<View> View_
{
get { return _View; }
set { _View = value; }
}
ICommand _Print_Line = new SimpleDelegateCommand((x) => MessageBox.Show(x.ToString()));
ICommand _Add_Line = new SimpleDelegateCommand((x) =>
View_ = new ObservableCollection<View>() /////////Error HERE
{
new View(){View_String = x.ToString()}
}
);
public ViewModel()
{
View_ = new ObservableCollection<View>()
{
new View(){View_String = "Setting 1"},
new View(){View_String = "Setting 2"}
};
}
public ICommand Print_Line { get { return _Print_Line; } }
public ICommand Add_Line { get { return _Add_Line; } }
}
How do I go about adding to my ObservableCollection using an ICommand command? or how do I go about it?
Also, how do you perform multiple tasks using an ICommand command, for example:
ICommand _Print_Line = new SimpleDelegateCommand((x) => MessageBox.Show(x.ToString()); MessageBox.Show("Second task"));
perform multiple tasks:
_Print_Line = new SimpleDelegateCommand((x) => {
MessageBox.Show(x.ToString());
MessageBox.Show("Second task");
});
Add private set to your command's field, for access it just from your class
private ICommand print_Line;
public ICommand Print_Line {
get { return print_Line; }
private set { print_Line = value; }
}
private ICommand add_Line;
public ICommand Add_Line {
get { return add_Line; }
private set { add_Line = value; }
}
maybe can help this way too:
private ICommand print_Line;
public ICommand Print_Line { get { return print_Line; } }
private ICommand add_Line;
public ICommand Add_Line{ get { return add_Line; } }
Move your Commands Initialization code inside the constructor of your ViewModel class. You are trying to access View_ which is not yet constructed yet and hence giving error. Object initializer outside constructor should not call the instance methods/properties as the class is not constructed till that time.
ICommand _Print_Line;
ICommand _Add_Line;
public ViewModel()
{
_Print_Line = new SimpleDelegateCommand((x) => MessageBox.Show(x.ToString()));
_Add_Line = new SimpleDelegateCommand((x) =>
View_ = new ObservableCollection<View>() /////////Error HERE
{
new View(){View_String = x.ToString()}
}
);
View_ = new ObservableCollection<View>()
{
new View(){View_String = "Setting 1"},
new View(){View_String = "Setting 2"}
};
}
First of all, your code is barely readable. The error is pretty straight forward. When you initialize a field, you cannot reference a non-static field.
ICommand _Add_Line is an instance field. Just as _View is. If you want to reference it, initialize the ICommand _Add_Line within the constructor of the class. Every time you call a non-static field or method, you need an instance of that class to get its value.
There are several answers on this issue on stackoverflow