WPF将多个参数传递给viewmodel(轻松)

时间:2017-05-16 19:43:32

标签: c# wpf mvvm

我正在使用MVVM模式,我发现WPF过于复杂而无法使用。每个小任务都需要多行代码。我遇到了一个非常简单的问题,我需要解决这个问题。但是我发现的每一条指令(转换器,多重绑定......)对于这么简单的任务来说似乎太复杂了。这是一个例子:

My application

单击按钮“Svar”时,应将“对象a”(类型object)和对象b(类型string)发送到ViewModel。我已经实现了ICommand并且传递了列表项,但似乎只是传递了一点信息突然又需要几十行代码。你们将如何处理这项任务?

更新: 一些代码。视图模型:

class ViewModelMain : ViewModelBase
{
    public object _selectedItem { get; set; }
    ICommand _answer;

    public void AnalyzeAnswer(MemEntity memEntity)
    {
        if(ReviewService.IsCorrectAnswer("", memEntity))
        Console.Beep(1000, 200);
    }

    public ICommand Answer
    {
        get
        {
            if (_answer == null)
            {
                _answer = new RelayCommand(
                    p => true,
                    p => this.AnalyzeAnswer((MemEntity)p));
            }
            return _answer;
        }
    }

    public ObservableCollection<MemEntity> items { get; set; }

    public object SelectedItem
    {
        get
        {
            return _selectedItem;
        }
        set
        {
            Console.Beep(1000, 200);
            _selectedItem = value;
            OnPropertyChanged("SelectedItem");
        }
    }

    public ViewModelMain()
    {
        items = new ObservableCollection<MemEntity> {
        new MemEntity { Word1 = "a", Correct = 3, Incorrect = 1 },
        new MemEntity { Word1 = "b", Correct = 1, Incorrect = 0 },
        new MemEntity { Word1 = "c", Correct = 30, Incorrect = 5 }
    };
}

查看:

<Grid>
    <ListBox x:Name="items" SelectedItem="{Binding SelectedItem, Mode=TwoWay, NotifyOnTargetUpdated=True, NotifyOnSourceUpdated=True}" HorizontalAlignment="Left" Height="266" Margin="10,35,0,0" VerticalAlignment="Top" Width="174" ItemsSource="{Binding items}" DisplayMemberPath="Word1"/>
    <TextBlock HorizontalAlignment="Left" Margin="189,35,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="138" Text="{Binding SelectedItem.Word1}"/>
    <ProgressBar HorizontalAlignment="Left" Height="14" Margin="189,212,0,0" VerticalAlignment="Top" Width="138" Value="{Binding SelectedItem.Proficiency, Mode=OneWay}" Foreground="#FF0672B0"/>
    <TextBox HorizontalAlignment="Left" Height="20" Margin="189,75,0,0" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="138" RenderTransformOrigin="-0.025,0.478"/>
    <Button Command="{Binding Path=DoSomethingCommand}" CommandParameter="{Binding SelectedItem}" Content="Svar" HorizontalAlignment="Left" Margin="331,75,0,0" VerticalAlignment="Top" Width="78"/>
    <Label Content="Statistikk" HorizontalAlignment="Left" Margin="189,181,0,0" VerticalAlignment="Top" Width="138"/>
    <Label Content="3 korrekt og 2 feil" HorizontalAlignment="Left" Margin="189,226,0,0" VerticalAlignment="Top" Width="108"/>
    <ToolBarTray HorizontalAlignment="Left" VerticalAlignment="Top" Width="517">
        <ToolBar VerticalAlignment="Top" Margin="0,0,-79,0">
            <Button Content="Lagre" VerticalAlignment="Top" />
            <Button Content="Åpne" VerticalAlignment="Top"/>
        </ToolBar>
    </ToolBarTray>
    <StatusBar HorizontalAlignment="Left" Height="24" Margin="0,306,0,0" VerticalAlignment="Top" Width="517"/>
</Grid>

1 个答案:

答案 0 :(得分:2)

1)如果您的SelectedItemMemEntity,请将其声明为MemEntity,而不是object;

2)将TextBox.Text属性绑定到ViewModel中的字符串属性;

3)将命令绑定到一个没有参数的简单Action,在其中调用objectstring;

4)使用C#-6.0 nameof功能引发属性更改通知。

这样的事情:

public class ViewModelMain : ViewModelBase
{
    public ViewModelMain()
    {
        Items = new ObservableCollection<MemEntity> {
            new MemEntity { Word1 = "a", Correct = 3, Incorrect = 1 },
            new MemEntity { Word1 = "b", Correct = 1, Incorrect = 0 },
            new MemEntity { Word1 = "c", Correct = 30, Incorrect = 5 }
        };
    }

    public ICommand Answer
    {
        get
        {
            if (_answer == null)
            {
                _answer = new RelayCommand(
                    p => true,
                    p => AnalyzeAnswer());
            }
            return _answer;
        }
    }
    private ICommand _answer;

    public void AnalyzeAnswer()
    {
        //use SelectedItem and Text in this method,
        //you don't need to pass them as parameters
    }

    public string Text { get; set; }

    public ObservableCollection<MemEntity> Items { get; set; }

    public MemEntity SelectedItem
    {
        get
        {
            return _SelectedItem;
        }
        set
        {
            Console.Beep(1000, 200);
            _SelectedItem = value;
            OnPropertyChanged(nameof(SelectedItem));
        }
    }
    private MemEntity _SelectedItem;
}

在xaml中,将布局属性分开(边距,大小等),Button将是:

<Button Command="{Binding Path=DoSomethingCommand}"
        Content="Svar"/>

TextBox

<TextBox Text="{Binding Path=Text}"/>

没有最简单和最短的方式。 MVVM看起来很冗长,但它是最低要求:

  1. 将UI与逻辑分离;
  2. 将这两者松散地绑在一起;
  3. 为您提供所需的所有功能。