Reputation: 547
I want to bind a method of a model to a button control in ListViewItem template. How can I do that in WPF? I tried but I get an error in runtime.
I just need a very simple and proper way to bind a method to button click event. Please help me out. I am new in WPF.
This is my code.....
<ListView Grid.Row="1"
MaxHeight="500"
Name="entryLisView"
Grid.ColumnSpan="2">
<ListView.ItemTemplate>
<DataTemplate>
<Grid Background="White">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock Text="New"
Margin="10,5,0,5"
VerticalAlignment="Top"
HorizontalAlignment="Left" />
<Button Name="cancelThisBtn"
Content="Delete"
Visibility="{Binding ItemCount, Mode=OneWay, Converter={StaticResource EduListItemCancelBtnVisibilityConverter}}"
Grid.Column="1"
Margin="0,5,10,5"
Click="{Binding DeleteDegree}"
VerticalAlignment="Top"
HorizontalAlignment="Right" />
<TextBox wpf:HintAssist.Hint="Exam or Degree Title"
Style="{DynamicResource MaterialDesignFloatingHintTextBox}"
Width="230"
FontSize="18"
Grid.Row="1"
Margin="10,0,10,0"
VerticalAlignment="Center"
HorizontalAlignment="Center"
Text="{Binding Title, Mode=TwoWay}" />
<TextBox wpf:HintAssist.Hint="Subject"
Style="{DynamicResource MaterialDesignFloatingHintTextBox}"
Width="230"
FontSize="18"
Margin="10,0,10,0"
Grid.Row="1"
Grid.Column="1"
Text="{Binding SubjectName, Mode=TwoWay}"
VerticalAlignment="Center"
HorizontalAlignment="Center" />
<TextBox wpf:HintAssist.Hint="Institute Name"
Style="{DynamicResource MaterialDesignFloatingHintTextBox}"
Width="230"
FontSize="18"
Margin="10,20,10,0"
Grid.Row="2"
Grid.Column="0"
Text="{Binding InstituteName, Mode=TwoWay}"
VerticalAlignment="Center"
HorizontalAlignment="Center" />
<TextBox wpf:HintAssist.Hint="Passing Year"
Style="{DynamicResource MaterialDesignFloatingHintTextBox}"
Width="230"
FontSize="18"
Margin="10,20,10,0"
Grid.Row="2"
Grid.Column="1"
Text="{Binding PassingYear, Mode=TwoWay}"
VerticalAlignment="Center"
HorizontalAlignment="Center" />
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
This is my model:
public class Degree : INotifyPropertyChanged
{
private int _id;
private string _title;
private string _instituteName;
private string _subjectName;
private string _passingYear;
private int _itemCount;
public string Title { get { return _title; } set { _title = value; RaisePropertyChanged(); } }
public string InstituteName { get { return _instituteName; } set { _instituteName = value; RaisePropertyChanged(); } }
public string SubjectName { get { return _subjectName; } set { _subjectName = value; RaisePropertyChanged(); } }
public string PassingYear { get { return _passingYear; } set { _passingYear = value; RaisePropertyChanged(); } }
public int Id { get { return _id; } set { _id = value; } }
public int ItemCount { get { return _itemCount; } set { _itemCount = value; RaisePropertyChanged(); } }
public Degree()
{
}
public void DeleteDegree(object sender, RoutedEventArgs e)
{
MessageBox.Show("I got u!");
}
//if (AddNewEducationDialog.Current != null)
//{
// AddNewEducationDialog.Current.degrees.Remove(this);
//}
public event PropertyChangedEventHandler PropertyChanged;
void RaisePropertyChanged([CallerMemberName]string name = null)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(name));
}
}
}
Upvotes: 0
Views: 519
Reputation: 370
You can't bind Methods in MVVM. You need to use Commands instead. Commands are triggered by default action behaviors of controls (e.g. for Button the default trigger is the Click) (if you want to bind commands to other events than default, you need to write some interaction logic or use a library that supports it).
Here is an example of the Command:
private ICommand _ShowEntitiesCommand;
public ICommand ShowEntitiesCommmand
{
get
{
if (_ShowEntitiesCommand == null)
{
_ShowEntitiesCommand = new RelayCommand(ShowEntities);
}
return _ShowEntitiesCommand;
}
}
private void ShowEntities(object parameter)
{
SelectedViewModel = viewModelLocator.Get(parameter);
}
Then on the button you just set the Command property: Command="{Binding ShowEntitiesCommmand}" CommandParameter="{Binding SomeParameterYoudLikeToPass}"
And here you can check an example of the RelayCommand class implementing the ICommand: https://github.com/Nidrax/Veritaware.Toolkits.LightVM/blob/master/Veritaware.Toolkits.LightVM.Net/RelayCommand.cs
Upvotes: 1
Reputation: 37790
If you use data binding, don't deal with Click
events. Use Button.Command
, and bind it to view model's ICommand
property:
public class SomeVm
{
public SomeVm()
{
// initialize SomeCommand here;
// usually you need RelayCommand/DelegateCommand
SomeCommand = new RelayCommand(SomeMethod);
}
public ICommand SomeCommand { get; }
private void SomeMethod()
{
}
}
XAML:
<Button Content="Click me!" Command="{Binding SomeCommand}"/>
Upvotes: 2