Hello Dear Programmers
I decided to learn MVVP pattern using C# language. That is why I have one question for you. I have a very simple application which consists of 5 textboxes and one button. It is not finished yet.
What I achieved:
When I write some text in first textbox (Employee Name), dynamic
search launches and all matched records appear in a list.
When I click a record in a list, information appears in textboxes.
What I want to achieve:
When I write some text in first textbox (Employee Name), dynamic
search launches and all matched records appear in a list.
When I click a record in a list, information appears in textboxes.
When I edit first textbox (Employee Name), Employee Name in a list
should not be changed. (Only after button click).
Observations:
I read about Multibinding, Converters and UpdateSourcetrigger: Explicit and Propertychanged. I tried to multibind a textbox TextboxEmployeeName. When I set PropertyChanged, Dynamic search works but Employee Name in a list is changed when I write in Textbox, but when I set Explicit, Employee Name in a list does not change (what I want to achieve) but dynamic search does not work.
My question is: How to set adequate UpdateSourceTrigger according to condition?
If (Record is not selected)
{
UpdateSourceTrigger = PropertyChanged
}
Else If (Record is selected)
{
UpdateSourceTrigger = Explicit
}
I dont know if I take a good way to solve my problem. Maybe you know better solution? Could you help me? Below I placed my entire code:
Employee.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.ComponentModel;
using System.Windows;
using System.Collections.ObjectModel;
using System.Windows.Data;
using System.Windows.Threading;
namespace OneWayTwoWayBinding
{
public class Employee : INotifyPropertyChanged
{
private string employeeName;
private string employeeID;
private int? employeeSalary;
private string employeeDesigner;
private string employeeEmailID;
private Employee selectedEmployee;
private ICollectionView filteredCollection;
private Employee dynamicSearch;
private int changedPathBinding;
public string EmployeeName
{
get
{
//Application.Current.Dispatcher.BeginInvoke(new Action(() => MessageBox.Show(employeeName)));
return employeeName;
}
set
{
employeeName = value;
if (FilteredCollection != null)
FilteredCollection.Filter = x => (String.IsNullOrEmpty(employeeName) || ((Employee)x).EmployeeName.Contains(employeeName));
OnPropertyChanged("EmployeeName");
}
}
public string EmployeeID
{
get
{
return employeeID;
}
set
{
employeeID = value;
OnPropertyChanged("EmployeeID");
}
}
public int? EmployeeSalary
{
get
{
return employeeSalary;
}
set
{
employeeSalary = value;
OnPropertyChanged("EmployeeSalary");
if (FilteredCollection != null)
FilteredCollection.Filter = x => ((employeeSalary == null) || ((Employee)x).EmployeeSalary == employeeSalary);
}
}
public string EmployeeDesigner
{
get
{
//Application.Current.Dispatcher.BeginInvoke(new Action(() => MessageBox.Show(employeeDesigner)));
return employeeDesigner;
}
set
{
employeeDesigner = value;
OnPropertyChanged("EmployeeDesigner");
if (FilteredCollection != null)
FilteredCollection.Filter = x => (String.IsNullOrEmpty(employeeDesigner) || ((Employee)x).EmployeeDesigner.Contains(employeeDesigner));
}
}
public string EmployeeEmailID
{
get
{
return employeeEmailID;
}
set
{
employeeEmailID = value;
OnPropertyChanged("EmployeeEmailID");
}
}
public IList<Employee> EmployeeList
{
get; set;
}
public Employee SelectedEmployee
{
get
{
//Application.Current.Dispatcher.BeginInvoke(new Action(() => MessageBox.Show(selectedEmployee.SelectedEmployee.ToString())));
return selectedEmployee;
}
set
{
selectedEmployee = value;
OnPropertyChanged("SelectedEmployee");
}
}
public Employee DynamicSearch
{
get
{
return dynamicSearch;
}
set
{
dynamicSearch = value;
OnPropertyChanged("DynamicSearch");
//FilteredCollection.Filter = x => (String.IsNullOrEmpty(dynamicSearch.EmployeeName) || ((Employee)x).EmployeeName.Contains(dynamicSearch.EmployeeName));
}
}
public ICollectionView FilteredCollection
{
get
{
return filteredCollection;
}
set
{
filteredCollection = value;
OnPropertyChanged("FilteredCollection");
}
}
public int ChangedPathBinding
{
get
{
//Application.Current.Dispatcher.BeginInvoke(new Action(() => MessageBox.Show(changedPathBinding.ToString())));
return changedPathBinding;
}
set
{
changedPathBinding = value;
OnPropertyChanged("ChangedPathBinding");
//SelectedEmployee.EmployeeName
}
}
public ObservableCollection<Employee> Employees { get; private set; }
public event PropertyChangedEventHandler PropertyChanged = null;
virtual protected void OnPropertyChanged(string propName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propName));
}
}
}
EmployeeViewModel.cs
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Data;
using System.Windows.Input;
namespace OneWayTwoWayBinding
{
public class EmployeeViewModel : Employee
{
public EmployeeViewModel()
{
ObservableCollection<Employee> Employees = new ObservableCollection<Employee>()
{
new Employee{EmployeeName = "Adrian",EmployeeID = "1",EmployeeSalary = 15000,EmployeeDesigner = "SoftwareEngingeer12312", EmployeeEmailID = "drozd001#gmail423423.com"},
new Employee{EmployeeName = "Bartek",EmployeeID = "2",EmployeeSalary = 15000,EmployeeDesigner = "SoftwareEngingeer",EmployeeEmailID = "drozd001#gmail.com"},
new Employee{EmployeeName = "Czarek",EmployeeID = "3",EmployeeSalary = 30000,EmployeeDesigner = "SoftwareEngingeer",EmployeeEmailID = "drozd001#gmail.com"}
};
FilteredCollection = CollectionViewSource.GetDefaultView(Employees);
//SelectedEmployee = new Employee {EmployeeName = string.Empty, EmployeeID = string.Empty, EmployeeSalary = string.Empty, EmployeeDesigner = string.Empty, EmployeeEmailID = string.Empty};
//EmployeeDesigner = "SoftwareEngingeer12312";
//EmployeeDesigner = "SoftwareEngingeer12312";
//DynamicSearch.EmployeeName = "Czarek";
//EmployeeSalary = 10;
ChangedPathBinding = -1;
SelectedEmployee = null;
}
RelayCommand _saveCommand;
public ICommand SaveCommand
{
get
{
if (_saveCommand == null)
{
_saveCommand = new RelayCommand((param) => this.Save(param),
param => this.CanSave);
}
return _saveCommand;
}
}
public void Save(object parameter)
{
FilteredCollection.Filter = null;
SelectedEmployee = null;
EmployeeName = null;
EmployeeSalary = null;
}
bool CanSave
{
get
{
return true;
}
}
}
}
MainWindow.xaml.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace OneWayTwoWayBinding
{
/// <summary>
/// Logika interakcji dla klasy MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
DataContext = new EmployeeViewModel();
}
}
}
Converters.cs
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Data;
namespace OneWayTwoWayBinding
{
public class Converters : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
//value = 5; //ta liczba pojawi sie w textbox po uruchomieniu aplikacji
return value;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
if (string.IsNullOrEmpty(value.ToString()))
return null;
//int var;
//var = int.Parse(value.ToString());
//var *= 2;
//value = var;
return value; //liczba wpisana w textbox z poziomu widoku aplikacji
}
}
public class ConverterFiltering : IMultiValueConverter
{
public object Convert(object[] value, Type targetType, object parameter, CultureInfo culture)
{
if (value[0] == DependencyProperty.UnsetValue || value[1] == DependencyProperty.UnsetValue)
{
return value[0];
}
MessageBox.Show("Values[0]: " + value[0].ToString());
//MessageBox.Show("Values[1]: " + value[1].ToString());
return value[0];
}
public object[] ConvertBack(object value, Type[] targetType, object parameter, CultureInfo culture)
{
string[] values = new string[2];
values[0] = value.ToString();
values[1] = value.ToString();
MessageBox.Show("Values[0]: " + values[0].ToString() + " Values[1]: " + values[1].ToString());
return values;
}
}
}
MainWindow.xaml
<Window x:Class="OneWayTwoWayBinding.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:OneWayTwoWayBinding"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Window.Resources>
<local:Converters x:Key="NullableValueConverter" />
<local:ConverterFiltering x:Key="ConverterFiltering" />
</Window.Resources>
<Grid Margin="0,0,0,20">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<ListView Name="EmployeeListView" HorizontalAlignment="Left" Height="160" Margin="0,259,0,0" VerticalAlignment="Top" Width="792" ItemsSource="{Binding FilteredCollection}" SelectedItem="{Binding SelectedEmployee, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" SelectedIndex="{Binding ChangedPathBinding}" >
<ListView.View>
<GridView>
<GridViewColumn Header="EmployeeName" Width="150" DisplayMemberBinding="{Binding EmployeeName}" />
<GridViewColumn Header="EmployeeID" Width="150" DisplayMemberBinding="{Binding EmployeeID}" />
<GridViewColumn Header="EmployeeSalary" Width="150" DisplayMemberBinding="{Binding EmployeeSalary}" />
<GridViewColumn Header="EmployeeDesigner" Width="150" DisplayMemberBinding="{Binding EmployeeDesigner}" />
<GridViewColumn Header="EmployeeEmailID" Width="150" DisplayMemberBinding="{Binding EmployeeEmailID}" />
</GridView>
</ListView.View>
</ListView>
<Label Content="Employee Name" HorizontalAlignment="Left" Margin="15,52,0,0" VerticalAlignment="Top" Width="77" Height="23"/>
<TextBox Name ="TextboxEmployeeName" HorizontalAlignment="Left" Height="23" Margin="97,52,0,0" VerticalAlignment="Top" Width="522" >
<TextBox.Text>
<MultiBinding Converter="{StaticResource ConverterFiltering}" Mode="TwoWay" UpdateSourceTrigger="PropertyChanged">
<Binding Path="SelectedEmployee.EmployeeName" Mode="TwoWay" UpdateSourceTrigger="PropertyChanged" />
<Binding Path="EmployeeName" Mode="TwoWay" UpdateSourceTrigger="PropertyChanged"/>
</MultiBinding>
</TextBox.Text>
</TextBox>
<Label Content="Label" HorizontalAlignment="Left" Margin="15,91,0,0" VerticalAlignment="Top" Width="77" Height="23"/>
<TextBox HorizontalAlignment="Left" Height="23" Margin="97,91,0,0" Text="{Binding Path=SelectedEmployee.EmployeeID, Mode=TwoWay}" VerticalAlignment="Top" Width="522"/>
<Label Content="Label" HorizontalAlignment="Left" Margin="15,131,0,0" VerticalAlignment="Top" Width="77" Height="23"/>
<TextBox HorizontalAlignment="Left" Height="23" Margin="97,131,0,0" Text="{Binding EmployeeSalary, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, Converter={StaticResource NullableValueConverter}}" VerticalAlignment="Top" Width="522"/>
<Label Content="Label" HorizontalAlignment="Left" Margin="15,176,0,0" VerticalAlignment="Top" Width="77" Height="23"/>
<TextBox HorizontalAlignment="Left" Height="23" Margin="97,176,0,0" Text="{Binding EmployeeDesigner, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" VerticalAlignment="Top" Width="522"/>
<Label Content="Label" HorizontalAlignment="Left" Margin="15,221,0,0" VerticalAlignment="Top" Width="77" Height="23"/>
<TextBox HorizontalAlignment="Left" Height="23" Margin="97,221,0,0" Text="{Binding SelectedEmployee.EmployeeEmailID, Mode=TwoWay}" VerticalAlignment="Top" Width="522"/>
<Button Content="Button" HorizontalAlignment="Left" Margin="663,116,0,0" VerticalAlignment="Top" Width="75" RenderTransformOrigin="-0.017,0.456" Command="{Binding SaveCommand}"/>
</Grid>
</Window>
RelayCommand.cs
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;
namespace OneWayTwoWayBinding
{
public class RelayCommand : ICommand
{
#region Fields
readonly Action<object> _execute;
readonly Predicate<object> _canExecute;
#endregion // Fields
#region Constructors
public RelayCommand(Action<object> execute) : this(execute, null) { }
public RelayCommand(Action<object> execute, Predicate<object> canExecute)
{
if (execute == null)
throw new ArgumentNullException("execute");
_execute = execute; _canExecute = canExecute;
}
#endregion // Constructors
#region ICommand Members
[DebuggerStepThrough]
public bool CanExecute(object parameter)
{
return _canExecute == null ? true : _canExecute(parameter);
}
public event EventHandler CanExecuteChanged
{
add { CommandManager.RequerySuggested += value; }
remove { CommandManager.RequerySuggested -= value; }
}
public void Execute(object parameter) { _execute(parameter); }
#endregion // ICommand Members
}
}
Hmm, maybe this solution will be okay for you?
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Command;
using System.Collections.Generic;
using System.Linq;
namespace WpfApp1
{
public class EmployeeModel
{
public string Name { get; set; }
}
public class EmployeeViewModel : ViewModelBase
{
readonly EmployeeModel model;
string editName;
public EmployeeViewModel (EmployeeModel model)
{
this.model = model;
editName = Name;
SaveChanges = new RelayCommand (() => { Name = EditName; SaveChanges.RaiseCanExecuteChanged (); }, () => IsDirty);
}
public string Name
{
get => model.Name;
set
{
model.Name = value;
RaisePropertyChanged (nameof (Name));
}
}
public string EditName
{
get => editName;
set
{
editName = value;
RaisePropertyChanged (nameof (EditName));
SaveChanges.RaiseCanExecuteChanged ();
}
}
public bool IsDirty => editName != Name;
public RelayCommand SaveChanges { get; }
}
public class WindowViewModel
{
List<EmployeeModel> models = new List<EmployeeModel>
{
new EmployeeModel () { Name = "Janusz" },
new EmployeeModel () { Name = "Grażyna" },
new EmployeeModel () { Name = "John" },
};
public WindowViewModel ()
{
EmployeeViews = models.Select (x => new EmployeeViewModel (x)).ToList ();
}
public IEnumerable<EmployeeViewModel> EmployeeViews { get; }
public EmployeeViewModel SelectedEmployeeView { get; set; }
}
}
And xaml:
<Window x:Class="WpfApp1.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:WpfApp1"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Window.DataContext>
<local:WindowViewModel/>
</Window.DataContext>
<Grid>
<ListBox ItemsSource="{Binding EmployeeViews}"
SelectedItem="{Binding SelectedEmployeeView}"
DisplayMemberPath="Name" Margin="26,26,565.6,0"
Height="274"
VerticalAlignment="Top"
Width="202"
/>
<Button Command="{Binding SelectedEmployeeView.SaveChanges}"
Content="Save"
HorizontalAlignment="Left"
Height="36"
Margin="245,81,0,0"
VerticalAlignment="Top"
Width="133"/>
<TextBox Text="{Binding SelectedEmployeeView.EditName, UpdateSourceTrigger=PropertyChanged}"
HorizontalAlignment="Left"
Height="23"
Margin="255,35,0,0"
TextWrapping="Wrap"
VerticalAlignment="Top"
Width="120"/>
</Grid>
</Window>
I have solved my problem on my own. I have placed my entire code below :)
Employee.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.ComponentModel;
using System.Windows;
using System.Collections.ObjectModel;
using System.Windows.Data;
using System.Windows.Threading;
namespace OneWayTwoWayBinding
{
public class Employee : INotifyPropertyChanged
{
private string employeeName;
private string employeeID;
private int? employeeSalary;
private string employeeDesigner;
private string employeeEmailID;
private Employee selectedEmployee;
private ICollectionView filteredCollection;
private string dynamicSearch;
private int changedPathBinding;
public string EmployeeName
{
get
{
return employeeName;
}
set
{
employeeName = value;
if (FilteredCollection != null)
FilteredCollection.Filter = x => (String.IsNullOrEmpty(employeeName) || ((Employee)x).EmployeeName.Contains(employeeName));
OnPropertyChanged("EmployeeName");
}
}
public string EmployeeID
{
get
{
return employeeID;
}
set
{
employeeID = value;
OnPropertyChanged("EmployeeID");
}
}
public int? EmployeeSalary
{
get
{
return employeeSalary;
}
set
{
employeeSalary = value;
OnPropertyChanged("EmployeeSalary");
if (FilteredCollection != null)
FilteredCollection.Filter = x => ((employeeSalary == null) || ((Employee)x).EmployeeSalary == employeeSalary);
}
}
public string EmployeeDesigner
{
get
{
//Application.Current.Dispatcher.BeginInvoke(new Action(() => MessageBox.Show(employeeDesigner)));
return employeeDesigner;
}
set
{
employeeDesigner = value;
OnPropertyChanged("EmployeeDesigner");
if (FilteredCollection != null)
FilteredCollection.Filter = x => (String.IsNullOrEmpty(employeeDesigner) || ((Employee)x).EmployeeDesigner.Contains(employeeDesigner));
}
}
public string EmployeeEmailID
{
get
{
return employeeEmailID;
}
set
{
employeeEmailID = value;
OnPropertyChanged("EmployeeEmailID");
}
}
public IList<Employee> EmployeeList
{
get; set;
}
public Employee SelectedEmployee
{
get
{
//Application.Current.Dispatcher.BeginInvoke(new Action(() => MessageBox.Show(selectedEmployee.SelectedEmployee.ToString())));
return selectedEmployee;
}
set
{
selectedEmployee = value;
OnPropertyChanged("SelectedEmployee");
}
}
public string DynamicSearch
{
get
{
if (SelectedEmployee == null)
{
EmployeeName = dynamicSearch;
}
return dynamicSearch;
}
set
{
dynamicSearch = value;
OnPropertyChanged("DynamicSearch");
}
}
public ICollectionView FilteredCollection
{
get
{
return filteredCollection;
}
set
{
filteredCollection = value;
OnPropertyChanged("FilteredCollection");
}
}
public int ChangedPathBinding
{
get
{
//Application.Current.Dispatcher.BeginInvoke(new Action(() => MessageBox.Show(changedPathBinding.ToString())));
return changedPathBinding;
}
set
{
changedPathBinding = value;
OnPropertyChanged("ChangedPathBinding");
//SelectedEmployee.EmployeeName
}
}
public ObservableCollection<Employee> Employees { get; private set; }
public event PropertyChangedEventHandler PropertyChanged = null;
virtual protected void OnPropertyChanged(string propName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propName));
}
}
}
EmployeeViewModel.cs
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Data;
using System.Windows.Input;
namespace OneWayTwoWayBinding
{
public class EmployeeViewModel : Employee
{
public EmployeeViewModel()
{
ObservableCollection<Employee> Employees = new ObservableCollection<Employee>()
{
new Employee{EmployeeName = "Adrian",EmployeeID = "1",EmployeeSalary = 15000,EmployeeDesigner = "SoftwareEngingeer12312", EmployeeEmailID = "drozd001#gmail423423.com"},
new Employee{EmployeeName = "Bartek",EmployeeID = "2",EmployeeSalary = 15000,EmployeeDesigner = "SoftwareEngingeer",EmployeeEmailID = "drozd001#gmail.com"},
new Employee{EmployeeName = "Czarek",EmployeeID = "3",EmployeeSalary = 30000,EmployeeDesigner = "SoftwareEngingeer",EmployeeEmailID = "drozd001#gmail.com"}
};
FilteredCollection = CollectionViewSource.GetDefaultView(Employees);
//SelectedEmployee = new Employee {EmployeeName = string.Empty, EmployeeID = string.Empty, EmployeeSalary = string.Empty, EmployeeDesigner = string.Empty, EmployeeEmailID = string.Empty};
//EmployeeDesigner = "SoftwareEngingeer12312";
//EmployeeDesigner = "SoftwareEngingeer12312";
//DynamicSearch.EmployeeName = "Czarek";
//EmployeeSalary = 10;
ChangedPathBinding = -1;
SelectedEmployee = null;
}
RelayCommand _saveCommand;
public ICommand SaveCommand
{
get
{
if (_saveCommand == null)
{
_saveCommand = new RelayCommand((param) => this.Save(param),
param => this.CanSave);
}
return _saveCommand;
}
}
public void Save(object parameter)
{
string[] SearchedCollection = ((string)parameter).Split(new char[] { ':' });
SelectedEmployee.EmployeeName = SearchedCollection[0];
//FilteredCollection.Filter = null;
SelectedEmployee = null;
//EmployeeName = null;
//EmployeeSalary = null;
}
bool CanSave
{
get
{
return SelectedEmployee != null;
}
}
}
}
Converters.cs
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Data;
namespace OneWayTwoWayBinding
{
public class Converters : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
//value = 5; //ta liczba pojawi sie w textbox po uruchomieniu aplikacji
return value;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
if (string.IsNullOrEmpty(value.ToString()))
return null;
//int var;
//var = int.Parse(value.ToString());
//var *= 2;
//value = var;
return value; //liczba wpisana w textbox z poziomu widoku aplikacji
}
}
public class ConverterFiltering : IMultiValueConverter
{
public object Convert(object[] value, Type targetType, object parameter, CultureInfo culture)
{
if (value[0] == DependencyProperty.UnsetValue || value[1] == DependencyProperty.UnsetValue)
{
return value[0];
}
return value[0];
}
public object[] ConvertBack(object value, Type[] targetType, object parameter, CultureInfo culture)
{
string[] values = new string[2];
values[0] = value.ToString();
values[1] = value.ToString();
return values;
}
}
public class ConverterButton : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
string _employeeName = (string)values[0];
//MessageBox.Show("ButtonConverter: " + _employeeName);
return string.Format("{0}", _employeeName);
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
}
MainWindows.xaml.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace OneWayTwoWayBinding
{
/// <summary>
/// Logika interakcji dla klasy MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
DataContext = new EmployeeViewModel();
}
}
}
MainWindow.xaml
<Window x:Class="OneWayTwoWayBinding.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:OneWayTwoWayBinding"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Window.Resources>
<local:Converters x:Key="NullableValueConverter" />
<local:ConverterFiltering x:Key="ConverterFiltering" />
<local:ConverterButton x:Key="ConverterButton" />
</Window.Resources>
<Grid Margin="0,0,0,20">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<ListView Name="EmployeeListView" HorizontalAlignment="Left" Height="160" Margin="0,259,0,0" VerticalAlignment="Top" Width="792" ItemsSource="{Binding FilteredCollection}" SelectedItem="{Binding SelectedEmployee, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" SelectedIndex="{Binding ChangedPathBinding}" >
<ListView.View>
<GridView>
<GridViewColumn Header="EmployeeName" Width="150" DisplayMemberBinding="{Binding EmployeeName}" />
<GridViewColumn Header="EmployeeID" Width="150" DisplayMemberBinding="{Binding EmployeeID}" />
<GridViewColumn Header="EmployeeSalary" Width="150" DisplayMemberBinding="{Binding EmployeeSalary}" />
<GridViewColumn Header="EmployeeDesigner" Width="150" DisplayMemberBinding="{Binding EmployeeDesigner}" />
<GridViewColumn Header="EmployeeEmailID" Width="150" DisplayMemberBinding="{Binding EmployeeEmailID}" />
</GridView>
</ListView.View>
</ListView>
<Label Content="Employee Name" HorizontalAlignment="Left" Margin="15,52,0,0" VerticalAlignment="Top" Width="77" Height="23"/>
<TextBox Name ="TextboxEmployeeName" HorizontalAlignment="Left" Height="23" Margin="97,52,0,0" VerticalAlignment="Top" Width="522" >
<TextBox.Text>
<MultiBinding Converter="{StaticResource ConverterFiltering}" Mode="TwoWay" UpdateSourceTrigger="PropertyChanged">
<Binding Path="SelectedEmployee.EmployeeName" Mode="OneWay" UpdateSourceTrigger="PropertyChanged" />
<Binding Path="DynamicSearch" Mode="TwoWay" UpdateSourceTrigger="PropertyChanged"/>
</MultiBinding>
</TextBox.Text>
</TextBox>
<Label Content="Label" HorizontalAlignment="Left" Margin="15,91,0,0" VerticalAlignment="Top" Width="77" Height="23"/>
<TextBox HorizontalAlignment="Left" Height="23" Margin="97,91,0,0" Text="{Binding Path=SelectedEmployee.EmployeeID, Mode=TwoWay}" VerticalAlignment="Top" Width="522"/>
<Label Content="Label" HorizontalAlignment="Left" Margin="15,131,0,0" VerticalAlignment="Top" Width="77" Height="23"/>
<TextBox HorizontalAlignment="Left" Height="23" Margin="97,131,0,0" Text="{Binding EmployeeSalary, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, Converter={StaticResource NullableValueConverter}}" VerticalAlignment="Top" Width="522"/>
<Label Content="Label" HorizontalAlignment="Left" Margin="15,176,0,0" VerticalAlignment="Top" Width="77" Height="23"/>
<TextBox HorizontalAlignment="Left" Height="23" Margin="97,176,0,0" Text="{Binding EmployeeDesigner, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" VerticalAlignment="Top" Width="522"/>
<Label Content="Label" HorizontalAlignment="Left" Margin="15,221,0,0" VerticalAlignment="Top" Width="77" Height="23"/>
<TextBox HorizontalAlignment="Left" Height="23" Margin="97,221,0,0" Text="{Binding SelectedEmployee.EmployeeEmailID, Mode=TwoWay}" VerticalAlignment="Top" Width="522"/>
<Button Content="Button" HorizontalAlignment="Left" Margin="663,116,0,0" VerticalAlignment="Top" Width="75" RenderTransformOrigin="-0.017,0.456" Command="{Binding SaveCommand}" >
<Button.CommandParameter>
<MultiBinding Converter="{StaticResource ConverterButton}" UpdateSourceTrigger="Explicit" Mode="TwoWay">
<Binding ElementName="TextboxEmployeeName" Path="Text"/>
</MultiBinding>
</Button.CommandParameter>
</Button>
</Grid>
</Window>
RelayCommand.cs
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;
namespace OneWayTwoWayBinding
{
public class RelayCommand : ICommand
{
#region Fields
readonly Action<object> _execute;
readonly Predicate<object> _canExecute;
#endregion // Fields
#region Constructors
public RelayCommand(Action<object> execute) : this(execute, null) { }
public RelayCommand(Action<object> execute, Predicate<object> canExecute)
{
if (execute == null)
throw new ArgumentNullException("execute");
_execute = execute; _canExecute = canExecute;
}
#endregion // Constructors
#region ICommand Members
[DebuggerStepThrough]
public bool CanExecute(object parameter)
{
return _canExecute == null ? true : _canExecute(parameter);
}
public event EventHandler CanExecuteChanged
{
add { CommandManager.RequerySuggested += value; }
remove { CommandManager.RequerySuggested -= value; }
}
public void Execute(object parameter) { _execute(parameter); }
#endregion // ICommand Members
}
}
Related
I want to use databinding in c#/WPF. Creating an object and using it as datacontext already works with its variables.
But I want to create classes in the datacontext object and use these variables.
The right binding should work with ....{Binding Path=Eyeobj.Farbe}....
Is the problem on the DataContenxt, class or the WPFs side?
MainWindow.xaml.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace DataContextDemo
{
/// <summary>
/// Interaktionslogik für MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
Person obj = new Person()
{
FirstName = "John",
LastName = "Smith",
Age = 30
};
public MainWindow()
{
InitializeComponent();
this.DataContext = obj;
}
}
}
MainWindow.xaml
<Window x:Class="DataContextDemo.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:DataContextDemo"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="80"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="30"/>
<RowDefinition Height="30"/>
<RowDefinition Height="30"/>
</Grid.RowDefinitions>
<TextBlock Margin="4" Text="First Name" VerticalAlignment="Center"/>
<TextBox Margin="4" Text="{Binding Path= FirstName}" Grid.Column="1"/>
<TextBlock Margin="4" Text="Last Name" Grid.Row="1" VerticalAlignment="Center"/>
<TextBox Margin="4" Text="{Binding Path= LastName}" Grid.Column="2" Grid.Row="1"/>
Person.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
namespace DataContextDemo
{
public class Person : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public Augen Eyeobj = new Augen("Red");
//public PropertyChangedEventHandler handler = PropertyChanged;
private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
public string FirstName
{
get
{
return this.firstName;
}
set
{
this.firstName = value;
NotifyPropertyChanged();
}
}
public string LastName
{
get
{
return this.lastName;
}
set
{
this.lastName = value;
NotifyPropertyChanged();
}
}
public int Age
{
get
{
return this.age;
}
set
{
this.age = value;
NotifyPropertyChanged();
}
}
private string firstName { get; set; }
public string lastName { get; set; }
public int age { get; set; }
}
}
<TextBlock Margin="4" Text="Age" Grid.Row="2" VerticalAlignment="Center"/>
<TextBox Margin="4" Text="{Binding Path = Eyeobj.Farbe}" Grid.Column="3" Grid.Row="2"/>
<TextBlock Margin="3" Text="{Binding Path=Eyeobj.Farbe}" Grid.Row="2" Grid.Column="3" x:Name="testbox"></TextBlock>
<Button Margin="4" Grid.Row="3" Click="Button_Click"></Button>
</Grid>
</Window>
Augen.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
namespace DataContextDemo
{
public class Augen : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public string farbe = "Blau";
public Augen(string farbe)
{
Farbe = farbe;
}
//public PropertyChangedEventHandler handler = PropertyChanged;
private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
public string Farbe
{
get
{
return this.farbe;
}
set
{
this.farbe = value;
NotifyPropertyChanged();
}
}
}
}
You use your Eyeobj as a field - it won't be visible from the view. Make the property, as you've done with the FirstName for example, implementing INotifyPropertyChanged.
private Augen _eyeobj;
public Augen Eyeobj
{
get
{
return _eyeobj;
}
set
{
if(_eyeobj != value)
{
_eyeobj = value;
NotifyPropertyChanged("Eyeobj");
}
}
}
I have this code:
using System;
using System.Collections.Generic;
using System.linq;
using System.Text;
using System.Threading.Tasks;
using System.Component-model;
namespace MEO.MODELS
{
public class Claims :INotifyPropertyChanged
{
public Claims()
{
}
private string description;
private string expenseHeaderId;
private string assginedTo;
private bool submitted;
private bool approved;
private bool authorised;
private DateTime updatedDate;
private DateTime createdDate;
private DateTime claimDate;
private DateTime lastModifiedDate;
private string expenseFormType;
public bool Approved
{
get
{
return this.approved;
}
set
{
if (value != this.approved)
{
this.approved = value;
this.NotfiyProperty("Approved");
}
}
}
public string AssignedTo
{
get
{
return this.assginedTo;
}
set
{
if (value != this.assginedTo)
{
this.assginedTo = value;
this.NotfiyProperty("AssignedTo");
}
}
}
public bool Authorised
{
get
{
return this.authorised;
}
set
{
if (value != authorised)
{
this.authorised = value;
this.NotfiyProperty("Authorised");
}
}
}
public bool Submitted
{
get
{
return this.submitted;
}
set
{
if (value != submitted)
{
this.submitted = value;
this.NotfiyProperty("Submitted");
}
}
}
public DateTime ClaimDate
{
get
{
return this.claimDate;
}
set
{
if (value != claimDate)
{
this.claimDate = value;
this.NotfiyProperty("ClaimDate");
}
}
}
public DateTime CreatedDate
{
get
{
return this.createdDate;
}
set
{
if (value != createdDate)
{
this.createdDate = value;
this.NotfiyProperty("CreatedDate");
}
}
}
public DateTime LastModifiedDate
{
get
{
return this.lastModifiedDate;
}
set
{
if (value != lastModifiedDate)
{
this.lastModifiedDate = value;
this.NotfiyProperty("LastModifiedDate");
}
}
}
public DateTime UpdatedDate
{
get
{
return this.updatedDate;
}
set
{
if (value != updatedDate)
{
this.updatedDate = value;
this.NotfiyProperty("UpdatedDate");
}
}
}
public string Description
{
get
{
return this.description;
}
set
{
if (value != this.description)
{
this.description = value;
this.NotfiyProperty("Description");
}
}
}
public string ExpenseFormType
{
get
{
return this.expenseFormType;
}
set
{
if (value != this.expenseFormType)
{
this.expenseFormType = value;
this.NotfiyProperty("ExpenseFormType");
}
}
}
public string ExpenseHeaderId
{
get
{
return this.expenseHeaderId;
}
set
{
if (value != this.expenseHeaderId)
{
this.expenseHeaderId = value;
this.NotfiyProperty("ExpenseHeaderId");
}
}
}
private void NotfiyProperty(string propertyName)
{
PropertyChangedEventHandler propertyChangedEventHandler = this.PropertyChanged;
if (propertyChangedEventHandler != null)
{
propertyChangedEventHandler.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
public event PropertyChangedEventHandler PropertyChanged;
}
}
And the following is the XAML which contains a Listbox.I have to bind the data getting from webservice calling a method called GetFullClaimLinesAsync by passing parameters when page is loaded.
<phone:PhoneApplicationPage
x:Class="MEO.Views.Result"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}"
SupportedOrientations="Portrait" Orientation="Portrait"
mc:Ignorable="d"
shell:SystemTray.IsVisible="True">
<!--LayoutRoot is the root grid where all page content is placed-->
<Grid x:Name="LayoutRoot" Background="White">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<StackPanel Grid.Row="0" Margin="12,17,0,28" Grid.ColumnSpan="2">
<Button Content="My Expenses On line" Background="#00ccff" Grid.Row="5" FontWeight="Bold" Name="head" Margin="-23,0,-13,-98" Foreground="White" BorderThickness="0"/>
</StackPanel>
<!--ContentPanel - place additional content here-->
<Grid x:Name="ContentPanel" Margin="0,35,24,10" Grid.ColumnSpan="2"/>
<!--<Button Content="Get Full Claims" Background="#00ccff" FontWeight="Bold" x:Name="claim" Click="claim_Click" Margin="67,105,97,-203" Foreground="White" BorderThickness="0" Grid.Row="1" RenderTransformOrigin="0.676,0.469"/>-->
<Grid Margin="0,203,10,-713" Grid.Row="1" >
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="0*"/>
</Grid.ColumnDefinitions>
<ListBox HorizontalAlignment="Left" Name="listbox1" ItemsSource="{Binding}" VerticalAlignment="Top" Height="500" Width="0">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<Grid Margin="10">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="50">
</ColumnDefinition>
<ColumnDefinition Width="50">
</ColumnDefinition>
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding Description}" Margin="=3" Grid.Column="0"></TextBlock>
<TextBlock Text="{Binding ExpenseHeaderId}" Margin="=3" Grid.Column="1"></TextBlock>
</Grid>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
</Grid>
</phone:PhoneApplicationPage>
and the following is the code behind file (Result.xaml.cs):
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Navigation;
using System.Xml.Linq;
using Microsoft.Phone.Controls;
using Microsoft.Phone.Shell;
using System.IO;
using System.Net.NetworkInformation;
using System.Text;
using System.ComponentModel;
using System.Collections.ObjectModel;
using MEO.MODELS;
namespace MEO.Views
{
public partial class Result : PhoneApplicationPage
{
//public Guid rid = new Guid(NavigationContext.QueryString["id"]);
//public string rpswd = NavigationContext.QueryString["password"];
//public DateTime headerFromDate = DateTime.Today;
//public DateTime detaiFromDate = DateTime.Today;
ObservableCollection<Claims> oc = new ObservableCollection<Claims>();
public Result()
{
InitializeComponent();
Guid rid = new Guid("0525466131154515");
string rpswd = "hchdj455mjchdjkch7dc1njj";
DateTime headerFromDate = Convert.ToDateTime("555525545");
DateTime detaiFromDate = Convert.ToDateTime("38635");
LoginService.DXDataMobileSoapClient client = new LoginService.DXDataMobileSoapClient();
client.GetFullClaimLinesCompleted+=client_GetFullClaimLinesCompleted;
client.GetFullClaimLinesAsync(rid, rpswd, "", headerFromDate, detaiFromDate, rid);
}
private void client_GetFullClaimLinesCompleted(object sender, LoginService.GetFullClaimLinesCompletedEventArgs e)
{
try
{
if (e.Error == null)
{
XElement[] array = Enumerable.ToArray<XElement>(e.Result.ReturnedDataTable.Any1.Descendants("ClaimHeadersDT"));
if (Enumerable.Count<XElement>(array) > 0)
{
//ObservableCollection<Claims> oc = new ObservableCollection<Claims>();
for (int i = 0; i < Enumerable.Count<XElement>(array); i++)
{
oc.Add(new Claims()
{
Description = (string)array[i].Element("h_description"),
ExpenseHeaderId =(string)array[i].Element("h_expense_headerID"),
});
}
listbox1.ItemsSource = oc;
}
}
}
catch(Exception ex)
{
throw ex;
}
}
}
}
My problem is that I am getting data from web service i.e. from XML and the data is added to my collection i.e. ObservableCollection oc. But I am unable to bind the oc data to list box. I am getting error in App.xaml like unhandeled exception. The error is not catched in my catch block. However Listbox.Itemssource has data, containing 603 items.
i think you get this problem because the listbox use a Model as Datatemplate, what you getting from the webserver is xml data and turning to a string, i did something like that before, and goas like that...
private void client_GetFullClaimLinesCompleted(class.......)
{
oc.ItemsSource = e.Result;
}
as you said, you're getting 603 results but they can't be recognized on DataTemplate Model
Looking for some advice on how I can achieve the following:
I'm currently building an C# wpf application and i want to add where the application on start up check if a specific usb is attached any of the usb ports
and if not the application cant be interacted till said usb is attached?
any ideas on how this can be done?
We can use the class System.IO.DriveInfo to retrieve all the drives on the system and look for drives where the DriveType is Removable. In addition, the removable drive (USB usually) must be ready, which is accessible as the property IsReady.
First off, we define a provider to retrieve the removable drives:
using System.Collections.Generic;
using System.IO;
using System.Linq;
namespace TestPopWpfWindow
{
public static class UsbDriveListProvider
{
public static IEnumerable<DriveInfo> GetAllRemovableDrives()
{
var driveInfos = DriveInfo.GetDrives().AsEnumerable();
driveInfos = driveInfos.Where(drive => drive.DriveType == DriveType.Removable);
return driveInfos;
}
}
}
Let us use the MVVM pattern also, so we define a ViewModelbase class, implementing INotifyPropertyChanged.
using System.ComponentModel;
namespace TestPopWpfWindow
{
public class ViewModelBase : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public void RaisePropertyChanged(string propertyName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
It is also handy to have an implemetation of ICommand:
using System;
using System.Windows.Input;
namespace TestPopWpfWindow
{
public class RelayCommand : ICommand
{
private Predicate<object> _canExecute;
private Action<object> _execute;
public RelayCommand(Predicate<object> canExecute, Action<object> execute)
{
_canExecute = canExecute;
_execute = execute;
}
public bool CanExecute(object parameter)
{
return _canExecute(parameter);
}
public event EventHandler CanExecuteChanged;
public void Execute(object parameter)
{
_execute(parameter);
}
}
}
We also set the DataContext of MainWindow to an instance of a demo view model defined afterwards:
namespace TestPopWpfWindow
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
DataContext = new UsbDriveInfoDemoViewModel();
}
}
}
We then define the view model itself and use System.Management.ManagementEventWatcher to look for changes in the drives mounted onto the system.
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Management;
using System.Windows;
using System.Windows.Input;
namespace TestPopWpfWindow
{
public class UsbDriveInfoDemoViewModel : ViewModelBase, IDisposable
{
public UsbDriveInfoDemoViewModel()
{
DriveInfos = new List<DriveInfo>();
ReloadDriveInfos();
RegisterManagementEventWatching();
TargetUsbDrive = #"E:\";
AccessCommand = new RelayCommand(x => true, x => MessageBox.Show("Functionality executed."));
}
public int UsbDriveCount { get; set; }
private string _targetUsbDrive;
public string TargetUsbDrive
{
get { return _targetUsbDrive; }
set
{
if (_targetUsbDrive != value)
{
_targetUsbDrive = value;
RaisePropertyChanged("TargetUsbDrive");
RaisePropertyChanged("DriveInfo");
}
}
}
public ICommand AccessCommand { get; set; }
private void ReloadDriveInfos()
{
var usbDrives = UsbDriveListProvider.GetAllRemovableDrives();
Application.Current.Dispatcher.Invoke(() =>
{
DriveInfos.Clear();
foreach (var usbDrive in usbDrives)
{
DriveInfos.Add(usbDrive);
}
UsbDriveCount = DriveInfos.Count;
RaisePropertyChanged("UsbDriveCount");
RaisePropertyChanged("DriveInfos");
});
}
public List<DriveInfo> DriveInfos { get; set; }
private ManagementEventWatcher _watcher;
private void RegisterManagementEventWatching()
{
_watcher = new ManagementEventWatcher();
var query = new WqlEventQuery("SELECT * FROM Win32_VolumeChangeEvent");
_watcher.EventArrived += watcher_EventArrived;
_watcher.Query = query;
_watcher.Start();
}
private void watcher_EventArrived(object sender, EventArrivedEventArgs e)
{
Debug.WriteLine(e.NewEvent);
ReloadDriveInfos();
}
public void Dispose()
{
if (_watcher != null)
{
_watcher.Stop();
_watcher.EventArrived -= watcher_EventArrived;
}
}
}
}
We also define a WPF multi-converter next to enable the button:
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Windows.Data;
namespace TestPopWpfWindow
{
public class UsbDriveAvailableEnablerConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
if (values == null || values.Count() != 2)
return false;
var driveInfos = values[1] as List<DriveInfo>;
var targetDrive = values[0] as string;
if (driveInfos == null || !driveInfos.Any() || string.IsNullOrEmpty(targetDrive))
return false;
return driveInfos.Any(d => d.IsReady && d.Name == targetDrive);
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
}
And we define a GUI to test this code:
<Window x:Class="TestPopWpfWindow.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:TestPopWpfWindow"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<Style x:Key="usbLabel" TargetType="Label">
<Style.Triggers>
<DataTrigger Binding="{Binding IsReady}" Value="False">
<Setter Property="Background" Value="Gray"></Setter>
</DataTrigger>
<DataTrigger Binding="{Binding IsReady}" Value="True">
<Setter Property="Background" Value="Green"></Setter>
</DataTrigger>
</Style.Triggers>
</Style>
<local:UsbDriveAvailableEnablerConverter x:Key="usbDriveAvailableEnablerConverter"></local:UsbDriveAvailableEnablerConverter>
</Window.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
</Grid.RowDefinitions>
<StackPanel Orientation="Vertical">
<TextBlock Text="USB Drive-detector" FontWeight="DemiBold" HorizontalAlignment="Center" FontSize="14" Margin="2"></TextBlock>
<TextBlock Text="Removable drives on the system" FontWeight="Normal" HorizontalAlignment="Center" Margin="2"></TextBlock>
<TextBlock Text="Drives detected:" FontWeight="Normal" HorizontalAlignment="Center" Margin="2"></TextBlock>
<TextBlock Text="{Binding UsbDriveCount, UpdateSourceTrigger=PropertyChanged}" FontWeight="Normal" HorizontalAlignment="Center" Margin="2"></TextBlock>
<ItemsControl Grid.Row="0" ItemsSource="{Binding DriveInfos, UpdateSourceTrigger=PropertyChanged}"
Width="100" BorderBrush="Black" BorderThickness="1">
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Vertical">
<Label Style="{StaticResource usbLabel}" Width="32" Height="32" FontSize="18" Foreground="White" Content="{Binding Name}">
</Label>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>
<Button Grid.Row="1" Height="24" Width="130" VerticalAlignment="Top" Margin="10" Content="Access functionality" Command="{Binding AccessCommand}">
<Button.IsEnabled>
<MultiBinding Converter="{StaticResource usbDriveAvailableEnablerConverter}">
<MultiBinding.Bindings>
<Binding Path="TargetUsbDrive"></Binding>
<Binding Path="DriveInfos"></Binding>
</MultiBinding.Bindings>
</MultiBinding>
</Button.IsEnabled>
</Button>
<StackPanel Grid.Row="2" Orientation="Horizontal" HorizontalAlignment="Center">
<TextBlock Margin="2" Text="Target this USB-drive:"></TextBlock>
<TextBox Margin="2" Text="{Binding TargetUsbDrive, UpdateSourceTrigger=LostFocus}" Width="100"></TextBox>
</StackPanel>
</Grid>
</Window>
I have now provided the Visual Studio 2013 solution with the code above available for download here:
https://onedrive.live.com/redir?resid=8EF5059044F781FC!40934&authkey=!AAkLBdsXTlMMTy4&ithint=file%2czip
Here's a post explaining how to get a list of all currently connected USB devices.
Get List of connected USB Devices
Friends I am using converter for the first time. I want to convert between Bool and String for the Visibility purpose of Button 'Help'. Getter-Setter for HelpVisibility are working but I am not sure why visibility of button is not working. Below is my code. Please help.
VehicalForm.xaml
<Window x:Class="Seris.VehicleForm"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="500" Width="650"
xmlns:l="clr-namespace:Seris.Converters">
<Window.Resources>
<l:Bool2String x:Key="converter" />
</Window.Resources>
<Control>
<Control.Template>
<ControlTemplate>
<WrapPanel Orientation="Vertical" Margin="10 " >
<Label Content="Vehical No" HorizontalAlignment="Left"/>
<TextBox Name="VehicalNo_Text" Height="23" Width="80" TextWrapping="Wrap" Text="{Binding VehicalNo, UpdateSourceTrigger=PropertyChanged}" HorizontalAlignment="Left" />
<Label Content="Model" HorizontalAlignment="Left"/>
<TextBox Name="Model_Text" Height="23" Width="80" TextWrapping="Wrap" Text="{Binding Model, UpdateSourceTrigger=PropertyChanged}" HorizontalAlignment="Left" />
<Label Content="Manufacturing Date" HorizontalAlignment="Left"/>
<DatePicker Name="ManufacturingDate_DateTime" SelectedDate="{Binding ManufacturingDate, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" Width="136"/>
<Label Content="IU No" HorizontalAlignment="Left"/>
<TextBox Height="23" Width="80" Name="IUNO_Text" TextWrapping="Wrap" Text="{Binding IUNo, UpdateSourceTrigger=PropertyChanged}" HorizontalAlignment="Left"/>
<Label Content="Personnel" HorizontalAlignment="Left"/>
<ComboBox Name="Personnel_Combo" SelectedValue="{Binding PersonnelNameSelected, UpdateSourceTrigger=PropertyChanged}" ItemsSource="{Binding PersonnelName, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" HorizontalAlignment="Left" Width="126"/>
<Separator Height="20" RenderTransformOrigin="0.5,0.5" Width="16"/>
<Button Name="Save_Button" Command="{Binding SaveButton_Command}" Content="Save" Width="66"/>
<Button Name="Replace_Button" CommandParameter="replace" IsEnabled="{Binding isEnableReplaceButton, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" Command="{Binding ReplaceButton_Command}" Content="Replace" Width="66"/>
<Button Name="Remove_Button" CommandParameter="replace" IsEnabled="{Binding isEnableReplaceButton, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" Command="{Binding RemoveButton_Command}" Content="Remove" Width="66"/>
<Label x:Name="Error_Label" Content="{Binding ErrorMessage, UpdateSourceTrigger=PropertyChanged}" Foreground="Red" HorizontalAlignment="Left" Height="41" Width="137"/>
<ListView Name ="Grid" Height="294" Width="371" >
<DataGrid Name="DG" ItemsSource="{Binding ListItems, UpdateSourceTrigger=PropertyChanged}" SelectedItem="{Binding SelectedRow, Mode=TwoWay}" GridLinesVisibility="None" IsReadOnly="True" AutoGenerateColumns="False" BorderThickness="0">
<DataGrid.Columns>
<DataGridTextColumn Header="Vehical No" Binding="{Binding VehicalNo}"/>
<DataGridTextColumn Header="Model" Binding="{Binding Model}" />
<DataGridTextColumn Header="ManufacturingDate" Binding="{Binding ManufacturingDate}" />
<DataGridTextColumn Header="IUNo" Binding="{Binding IUNo}" />
<DataGridTextColumn Header="Personnel" Binding="{Binding PersonnelNameSelected}" />
</DataGrid.Columns>
</DataGrid>
</ListView>
<TextBlock Name="Notification" Text="{Binding EditText, UpdateSourceTrigger=PropertyChanged}"/>
<ProgressBar Name="Progressbar" Minimum="0" Maximum="100" Value="{Binding Progress, UpdateSourceTrigger=PropertyChanged}" Height="11"/>
<TextBlock Text="{Binding ElementName=Progressbar, Path=Value, StringFormat={}{0:0}%}" HorizontalAlignment="Center" VerticalAlignment="Center" />
<Button Name="Help" Visibility="{Binding HelpVisibility, Converter={StaticResource converter}, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" CommandParameter="help" Height="50" Width="50" Click="Help_Click" HorizontalAlignment="Right">
<Image Height="45" Width="45" Source="../Images/help.jpg" HorizontalAlignment="Left"/>
</Button>
</WrapPanel>
</ControlTemplate>
</Control.Template>
</Control>
</Window>
Bool2String.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Data;
namespace Seris.Converters
{
class Bool2String : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (value is bool)
return bool.TrueString;
return null;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (value is string)
{
if (value == "true")
return true;
else if (value == "false")
return false;
}
return null;
}
}
}
VehicalMainViewModel.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Seris.Models;
using System.Collections.ObjectModel;
using System.Windows.Input;
using Seris.Commands;
using Seris.ViewModels;
using System.Windows;
using System.Windows.Controls;
using System.Threading;
using System.ComponentModel;
using Seris.Views;
namespace Seris.ViewModels
{
public class VehicleMainViewModel : ObservableObject
{
#region Getters-Setters
// Static Variables
private static bool _IsEnableReplaceButton;
public static bool IsEnableReplaceButton
{
get { return _IsEnableReplaceButton; }
set { _IsEnableReplaceButton = value; }
}
// Non-Static Variables
public ObservableCollection<VehicleModel> _listItems;
public ObservableCollection<VehicleModel> ListItems
{
get { return _listItems; }
set
{
if (value == null || (!value.Equals(_listItems)))
{
_listItems = value;
}
}
}
private int _Progress;
public int Progress
{
get { return _Progress; }
set { _Progress = value; OnPropertyChanged("Progress"); }
}
private string _ErroMesage;
public string ErrorMessage
{
get { return _ErroMesage; }
set
{
_ErroMesage = value; OnPropertyChanged("ErrorMessage");
if (ErrorMessage.Trim() == "" || ErrorMessage == null)
HelpVisibility = false;
else
HelpVisibility = true;
}
}
private bool _HelpVisibility;
public bool HelpVisibility
{
get { return _HelpVisibility; }
set { _HelpVisibility = value; OnPropertyChanged("HelpVisibility"); }
}
private Guid? _UniqueNo;
public Guid? UniqueNo
{
get { return _UniqueNo; }
set
{
if (value == null || (!value.Equals(_UniqueNo)))
{
_UniqueNo = value;
OnPropertyChanged("VehicalNo");
}
}
}
private string _VehicalNo;
public string VehicalNo
{
get { return _VehicalNo; }
set
{
if (value == null || (!value.Equals(_VehicalNo)))
{
_VehicalNo = value;
EditText = _VehicalNo;
OnPropertyChanged("VehicalNo");
}
}
}
private string _Model;
public string Model
{
get { return _Model; }
set
{
if (value == null || (!value.Equals(_Model)))
{
_Model = value;
EditText = _Model;
OnPropertyChanged("Model");
}
}
}
private DateTime? _ManufacturingDate;
public DateTime? ManufacturingDate
{
get { return _ManufacturingDate; }
set
{
if (value == null || (!value.Equals(_ManufacturingDate)))
{
_ManufacturingDate = value;
EditText = _ManufacturingDate.ToString();
OnPropertyChanged("ManufacturingDate");
}
}
}
private string _IUNo;
public string IUNo
{
get { return _IUNo; }
set
{
if (value == null || (!value.Equals(_IUNo)))
{
_IUNo = value;
EditText = _IUNo;
OnPropertyChanged("IUNo");
}
}
}
private ObservableCollection<string> _PersonnelName;
public ObservableCollection<string> PersonnelName
{
get { return _PersonnelName; }
set
{
if (value != _PersonnelName)
{
_PersonnelName = value;
EditText = _VehicalNo;
OnPropertyChanged("PersonnelName");
}
}
}
private string _PersonnelNameSelected;
public string PersonnelNameSelected
{
get { return _PersonnelNameSelected; }
set
{
if (value != _PersonnelNameSelected)
{
_PersonnelNameSelected = value;
EditText = _PersonnelNameSelected;
OnPropertyChanged("PersonnelNameSelected");
}
}
}
private string _EditText;
public string EditText
{
get { return _EditText; }
set
{
if (value != _EditText)
{
_EditText = value;
OnPropertyChanged("EditText");
}
}
}
private VehicleModel _SelectedRow;
public VehicleModel SelectedRow
{
get { return _SelectedRow; }
set
{
if (value != _SelectedRow)
{
_SelectedRow = value;
OnPropertyChanged("SelectedRow");
if (SelectedRow != null)
{
UniqueNo = _SelectedRow.UniqueNo;
VehicalNo = _SelectedRow.VehicalNo;
Model = _SelectedRow.Model;
ManufacturingDate = _SelectedRow.ManufacturingDate;
IUNo = _SelectedRow.IUNo;
PersonnelNameSelected = _SelectedRow.PersonnelNameSelected;
_IsEnableReplaceButton = true;
}
}
}
}
#endregion
#region Command Objects
private ICommand _saveButton_Command;
public ICommand SaveButton_Command
{
get { return _saveButton_Command; }
set { _saveButton_Command = value; }
}
private ICommand _ReplaceButton_Command;
public ICommand ReplaceButton_Command
{
get { return _ReplaceButton_Command; }
set { _ReplaceButton_Command = value; }
}
private ICommand _RemoveButton_Command;
public ICommand RemoveButton_Command
{
get { return _RemoveButton_Command; }
set { _RemoveButton_Command = value; }
}
#endregion
#region Methods
//Static Methods
#region Constructors
public VehicleMainViewModel()
{
// Initialization
VehicleModel vm = new VehicleModel();
ListItems = new ObservableCollection<VehicleModel>();
PersonnelName = ListOfPersonnelViewModel.PersonNameList_Updating;
//PersonnelName = new ObservableCollection<string>() { "ABC", "DEF", "GHI" };
// Setting Flags
ErrorMessage = "";
IsEnableReplaceButton = false;
//
// Commands Initialization
SaveButton_Command = new RelayCommand(new Action<object>(SaveToList));
ReplaceButton_Command = new RelayCommand(new Action<object>(ReplaceToList));
RemoveButton_Command = new RelayCommand(new Action<object>(RemoveList));
}
#endregion
}
}
In your converter you should return Visibilty.Visible or Visibility.Collapsed, not true or false or string .
Visibility property accepts value as "Hidden", "Collapse" or "Visible". You need to set these values to Visibility property.
You can refer following link for code to BoolToVisibilityconverter
WPF Converter Property
Please dont forget to like answer if you find it useful.
I am working on WPF, MVVM C# simple app for learning.
I do have my front-end having Table kind of structure using element ""
See "VehicalForm.xaml" below.
Below is code of my View as well as View-Model part. (I have given just necessary files. Please let me know if you need any other files)
App.xaml.cs
using Seris.ViewModels;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Windows;
namespace Seris
{
/// <summary>
/// Interaction logic for App.xaml
/// </summary>
public partial class App : Application
{
public void OnStartup(object sender, StartupEventArgs e)
{
VehicalForm vehicalForm = new VehicalForm();
vehicalForm.DataContext = new VehicalMainViewModel();
vehicalForm.Show();
}
}
}
VehicalForm.xaml
<Window x:Class="Seris.VehicalForm"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<WrapPanel Orientation="Vertical" Margin="10 " >
<Label Content="Vehical No" HorizontalAlignment="Left"/>
<TextBox Name="VehicalNo_Text" Height="23" TextWrapping="Wrap" Text="TextBox" HorizontalAlignment="Left"/>
<Label Content="Model" HorizontalAlignment="Left"/>
<TextBox Name="Model_Text" Height="23" TextWrapping="Wrap" Text="TextBox" HorizontalAlignment="Left" />
<Label Content="Manufacturing Date" HorizontalAlignment="Left"/>
<DatePicker/>
<Label Content="IU No" HorizontalAlignment="Left"/>
<TextBox Height="23" Name="IUNO_Text" TextWrapping="Wrap" Text="TextBox" HorizontalAlignment="Left"/>
<Label Content="Personnel" HorizontalAlignment="Left"/>
<ComboBox Name="Personnel_Combo" HorizontalAlignment="Left" Width="116"/>
<Separator Height="20" RenderTransformOrigin="0.5,0.5" Width="16"/>
<Button Name="Save_Button" Command="{Binding SaveToList}" Content="Save" Width="66"/>
<ListView Height="294" Width="371" >
<ListView Height="294" Width="371" ItemsSource="{Binding listItems, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" >
<ListView.View>
<GridView>
<GridViewColumn Header="Vehical No" DisplayMemberBinding="{Binding VehicalNo}" />
<GridViewColumn Header="Model" DisplayMemberBinding="{Binding Model}" />
<GridViewColumn Header="ManufacturingDate" DisplayMemberBinding="{Binding ManufacturingDate}" />
<GridViewColumn Header="IUNo" DisplayMemberBinding="{Binding IUNo}" />
<GridViewColumn Header="Personnel" DisplayMemberBinding="{Binding Personnel}" />
</GridView>
</ListView.View>
</ListView>
</WrapPanel>
VehicalForm.xaml.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace Seris
{
public partial class VehicalForm : Window
{
public VehicalForm()
{
InitializeComponent();
}
}
}
VehicalMainViewModel.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Seris.Models;
using System.Collections.ObjectModel;
using System.Windows.Input;
using Seris.Commands;
using Seris.ViewModels;
namespace Seris.ViewModels
{
public class VehicalMainViewModel : ObservableObject
{
ObservableCollection<VehicalModel> listItems = new ObservableCollection<VehicalModel>();
#region Getter-Setter
private string _VehicalNo;
public string VehicalNo
{
get { return _VehicalNo; }
set
{
if (value != _VehicalNo)
{
_VehicalNo = value.Trim();
if(OnPropertyChanged("VehicalNo"))
listItems.Add(new VehicalModel(VehicalNo, Model, ManufacturingDate, IUNo, PersonnelName));
}
}
}
private string _Model;
public string Model
{
get { return _Model; }
set
{
if (value != _Model)
{
_Model = value.Trim();
OnPropertyChanged("Model");
}
}
}
private DateTime _ManufacturingDate;
public DateTime ManufacturingDate
{
get { return _ManufacturingDate; }
set
{
if (value != _ManufacturingDate)
{
_ManufacturingDate = value;
OnPropertyChanged("ManufacturingDate");
}
}
}
private string _IUNo;
public string IUNo
{
get { return _IUNo; }
set
{
if (value != _IUNo)
{
_IUNo = value.Trim();
OnPropertyChanged("IUNo");
}
}
}
private string _PersonnelName;
public string PersonnelName
{
get { return _PersonnelName; }
set
{
if (value != _PersonnelName)
{
_PersonnelName = value.Trim();
OnPropertyChanged("PersonnelName");
}
}
}
#endregion
private ICommand _saveButton_Command;
public ICommand SaveButton_Command
{
get { return _saveButton_Command; }
set { _saveButton_Command = value; }
}
public void SaveToList(object o1)
{
listItems.Add(new VehicalModel(VehicalNo,Model,ManufacturingDate,IUNo,PersonnelName));
}
public void RemoveFromList()
{
}
public VehicalMainViewModel()
{
VehicalModel vm=new VehicalModel();
SaveButton_Command = new RelayCommand(new Action<object>(SaveToList));
}
}
}
ObservableObject.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Windows;
namespace Seris.Models
{
public abstract class ObservableObject: INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected bool OnPropertyChanged(string propertyName)
{
this.VerifyPropertyName(propertyName);
PropertyChangedEventHandler handler = PropertyChanged;
if(handler!=null)
{
if (propertyName != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
return true;
}
}
return false;
}
public void VerifyPropertyName(string propertyName)
{
if(TypeDescriptor.GetProperties(this)[propertyName]==null)
{
string msg = "Invalid Property Name: " + propertyName;
if (this.ThrowOnInvalidPropertyName)
throw new Exception(msg);
else
Debug.Fail(msg);
}
}
public bool ThrowOnInvalidPropertyName { get; set; }
}
}
VehicalModel.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
namespace Seris.Models
{
public class VehicalModel : ObservableObject
{
#region Getter-Setter
private string _VehicalNo;
public string VehicalNo
{
get { return _VehicalNo; }
set
{
if (value != _VehicalNo)
{
_VehicalNo = value.Trim();
OnPropertyChanged("VehicalNo");
}
}
}
private string _Model;
public string Model
{
get { return _Model; }
set
{
if (value != _Model)
{
_Model = value.Trim();
OnPropertyChanged("Model");
}
}
}
private DateTime _ManufacturingDate;
public DateTime ManufacturingDate
{
get { return _ManufacturingDate; }
set
{
if (value != _ManufacturingDate)
{
_ManufacturingDate = value;
OnPropertyChanged("ManufacturingDate");
}
}
}
private string _IUNo;
public string IUNo
{
get { return _IUNo; }
set
{
if (value != _IUNo)
{
_IUNo = value.Trim();
OnPropertyChanged("IUNo");
}
}
}
private string _PersonnelName;
public string PersonnelName
{
get { return _PersonnelName; }
set
{
if (value != _PersonnelName)
{
_PersonnelName = value.Trim();
OnPropertyChanged("PersonnelName");
}
}
}
#endregion
#region Constructor
public VehicalModel(string VehicalNo, string Model, DateTime ManufacturingDate, string IUNo, string PersonnelName)
{
this.VehicalNo = VehicalNo;
this.Model = Model;
this.ManufacturingDate = ManufacturingDate;
this.IUNo = IUNo;
this.PersonnelName = PersonnelName;
}
public VehicalModel()
{
this.VehicalNo = null;
this.Model = null;
this.ManufacturingDate = DateTime.Now;
this.IUNo = null;
this.PersonnelName = null;
}
#endregion
#region Methods
#region Validate Methods
public bool Validate_VehicalNo()
{
if (matchRE(VehicalNo,"[A-Zz-z][A-Zz-z0-9]{6}"))
return true;
else
return false;
}
public bool Validate_Model()
{
if(Model!=null)
return true;
else
return false;
}
public bool Validate_ManufacturingDate()
{
return true;
}
public bool Validate_IUNo()
{
if(matchRE(IUNo,"[0-9]{10}"))
return true;
else
return false;
}
public bool Validate_PersonnelName()
{
if(matchRE(PersonnelName,"[A-Za-z]+"))
return true;
else
return false;
}
public bool matchRE(string stringToMatch, string regularExpression)
{
Regex regex = new Regex(#regularExpression);
Match match = regex.Match(stringToMatch);
if(match.Success)
return(true);
else
return(false);
}
#endregion
#endregion
}
}
What I need is
1) When I update VehicalNo, new row should be added in the table.
2) If I need to update individual elements of every row in future which should reflect in table as soon as I update , is there inbuilt facility in ListView? Or I need to use List for individual elements (i.e. VehicalNo, Model, ... ) and put in one main List keeping eye using ObservableObject?
I don't know eventhough it is being added to list as well as I have implemented INotifyPropert using ObservableObject, why its not reflecting in front-end.
Please help.
Add
public ObservableCollection ListItems {get{return listItems;}}
to you VehicalMainViewModel and change binding to
ItemsSource="{Binding ListItems}"
P.S. your listItems is private field.
ok so heres an example of the first Text box and you can follow suit on the rest:
<Window x:Class="Seris.VehicalForm"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:local="clr-namespace:Seris.ViewModels"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Window.DataContext>
<local:VehicalMainViewModel/>
</Window.DataContext>
<Label Content="Vehical No" HorizontalAlignment="Left"/>
<TextBox Name="VehicalNo_Text" Height="23" TextWrapping="Wrap" Text="{Binding VehicalNo}" HorizontalAlignment="Left"/>
I cannot find any references at the moment but I would suggest looking at DataContext and Data Binding in WPF
EDIT
<Application x:Class="Seris.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="VehicalForm.xaml">
<Application.Resources>
</Application.Resources>
</Application>