我如何从视图中获取数据

时间:2010-08-13 06:34:10

标签: c# wpf

我使用MVVM来构建我的项目,现在我遇到了一些麻烦,当我点击一个按钮时,我想从视图中获取数据到viewmodel,我该怎么办?

感谢 鲍勃

2 个答案:

答案 0 :(得分:2)

将该数据绑定到视图模型,并在用户单击按钮时执行命令。命令和数据存放在视图模型中,因此它具有所需的一切。

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}"/>

有关上述示例中各种依赖项的信息,例如ViewModelDelegateCommand,请参阅我的series of posts on MVVM

收到更多信息后编辑:为了跟踪项目选择,只需引入一个视图模型来表示项目:

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);
             }
        }
    }
}

您的“主”视图模型会公开这些项目的集合(通常为ObservableCollection<T>):

public ICollection<CustomerViewModel> Customers
{
    get { return this.customers; }
}

您的视图将绑定为:

<ListBox ItemsSource="{Binding Customers}">
    <ListBox.ItemContainerStyle>
        <Style TargetType="ListBoxItem">
            <Setter Property="IsSelected" Value="{Binding IsSelected}"/>
        </Style>
    </ListBox.ItemContainerStyle>
</ListBox>

注意每个ListBoxItem如何将其IsSelected属性绑定到CustomerViewModel.IsSelected属性。因此,您的主视图模型可以只检查此属性以确定选择了哪些客户:

var selectedCustomers = this.Customers.Where(x => x.IsSelected);

答案 1 :(得分:0)

Kent建议的解决方案在我看来是迄今为止唯一一个遵循MVVM的解决方案。 但是,如果您不想将列表框选择复制/反映到视图模型,或者您想要快速 - 根据MVVM - 脏解决方案,则可以使用命令参数将数据从视图发送到视图模型。

为此,您必须将按钮的CommandParameter属性绑定到包含要发送到视图模型的数据的属性。为简单起见,我只使用了TextBox

<StackPanel Orientation="Vertical">
    <TextBox x:Name="Data"/>
    <Button Content="DoSomething" 
            Command="{Binding Path=DoSomethingCommand}" 
            CommandParameter="{Binding ElementName=Data, Path=Text}"/>
</StackPanel>

示例的ViewModel如下所示。

public class ViewModel
{
    private ICommand doSomethingCommand = new MyCommand();

    public ICommand DoSomethingCommand
    {
        get
        {
            return doSomethingCommand;
        }
    }
}

通过此操作,您将获得指定内容作为Execute 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);
    }
}