i use MVVM to buil开发者_Go百科t my project, now i have some troubles,when i click a button, i want get data from view to viewmodel, what should i do?
thanks Bob
Bind that data to the view model and execute a command when the user clicks the button. The command and data are housed in the view model, so it has everything it needs.
public class YourViewModel : ViewModel
{
private readonly ICommand doSomethingCommand;
private string data;
public YourViewModel()
{
this.doSomethingCommand = new DelegateCommand(this.DoSomethingWithData);
}
public ICommand DoSomethingCommand
{
get { return this.doSomethingCommand; }
}
public string Data
{
get { return this.data; }
set
{
if (this.data != value)
{
this.data = value;
this.OnPropertyChanged(() => this.Data);
}
}
}
private void DoSomethingWithData(object state)
{
// do something with data here
}
}
XAML:
<TextBox Text="{Binding Data}"/>
<Button Command="{Binding DoSomethingWithData}"/>
For information on the various dependencies in the above example such as ViewModel
and DelegateCommand
, see my series of posts on MVVM.
EDIT after receiving more info: For tracking item selection, simply introduce a view model to represent the item:
public class CustomerViewModel : ViewModel
{
private bool isSelected;
public bool IsSelected
{
get { return this.isSelected; }
set
{
if (this.isSelected != value)
{
this.isSelected = value;
this.OnPropertyChanged(() => this.IsSelected);
}
}
}
}
Your "main" view model would expose a collection of these items (generally an ObservableCollection<T>
):
public ICollection<CustomerViewModel> Customers
{
get { return this.customers; }
}
Your view would then bind as:
<ListBox ItemsSource="{Binding Customers}">
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="IsSelected" Value="{Binding IsSelected}"/>
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
Notice how each ListBoxItem
will have its IsSelected property bound to the CustomerViewModel.IsSelected
property. Thus, your main view model can just check this property to determine which customers are selected:
var selectedCustomers = this.Customers.Where(x => x.IsSelected);
The solution suggested by Kent is in my opinion by far the best/only one to follow MVVM. If however you don't want to replicate/reflect listbox selections to the view model or you want a quick and - according to MVVM - dirty solution, you can use the command parameter to send data from the view to the view model.
For that you have to bind the CommandParameter
property of the button to the property which contains the data you want to send to the view model. For simplicity I just used a TextBox
.
<StackPanel Orientation="Vertical">
<TextBox x:Name="Data"/>
<Button Content="DoSomething"
Command="{Binding Path=DoSomethingCommand}"
CommandParameter="{Binding ElementName=Data, Path=Text}"/>
</StackPanel>
The ViewModel of the sample looks like the following.
public class ViewModel
{
private ICommand doSomethingCommand = new MyCommand();
public ICommand DoSomethingCommand
{
get
{
return doSomethingCommand;
}
}
}
With this, you will get the specified content as the parameter in the Execute
method of ICommand
.
public class MyCommand : ICommand
{
public bool CanExecute(object parameter)
{
return true;
}
public event EventHandler CanExecuteChanged;
public void Execute(object parameter)
{
string dataFromView = (string)parameter;
// ...
MessageBox.Show(dataFromView);
}
}
精彩评论