【问题标题】:WPF MVVM: binding command to eventWPF MVVM:将命令绑定到事件
【发布时间】:2014-11-06 17:07:28
【问题描述】:

我有我的视图和视图模型文件。在我的视图模型中,我有这个简单的代码:

private void Filter(string keyword)
{
    Debug.Print("******START********");
    string stringToSearch = keyword.ToLower();
    ObservableCollection<TabImpianti> listBoxSource = new ObservableCollection<TabImpianti>();
    foreach (TabImpianti ti in p_ListaImpianti)
    {
        if (ti.NOME.ToString().ToLower().Contains(stringToSearch))
            listBoxSource.Add(ti);
    }
    p_ListaImpianti = listBoxSource;
    Debug.Print("******END********");
}

在我的 xaml 中,我有:

<dxe:TextEdit  ValidateOnTextInput="True" Margin="105,10,797,631" />

愚蠢的问题:如何将我的函数绑定到事件 EditValueChanged,同时传递文本框的内容作为参数?简单的目标是:当用户在文本框中写东西时,过滤绑定到视图模型的集合。

网上找了很多教程,代码sn-p之类的,不过都在帮助我理解。

【问题讨论】:

  • 如果你希望它发生在一个事件上,那么你需要使用触发器,但是如果你希望它发生在一个按钮点击中,你可以使用一个命令。
  • 我希望它发生在一个事件中!如何使用触发器?
  • 请检查下面给出的答案是否是您所需要的。

标签: c# wpf xaml mvvm binding


【解决方案1】:

您的 TextEdit 控件应绑定到 ViewModel 中的属性。在该属性的设置器中,您将调用 Filter 方法。

此示例假设您的 TextEdit 控件具有 Text 属性。如果没有,请更改为绑定到任何属性名称。

<dxe:TextEdit Text="{Binding MyTextValue}"  ValidateOnTextInput="True" Margin="105,10,797,631" />

然后在 ViewModel 类中:

private string _myTextValue;
public string MyTextValue {
    get {
        return _myTextValue;
    }
    set {
        if (value != _myTextValue) {
            _myTextValue = value;
            Filter(_myTextValue);
        }
    }
 }

【讨论】:

  • 这是不好的做法。属性设置器不应像这样调用可能长时间运行的操作。
  • @slugster 是什么让您认为这是一项长期运行的操作?问题中没有说明任何类似的内容。
  • 在问题中没有说明任何内容都没有关系 - 在 setter 中实现是一个不好的副作用。如果列表中最初有 1000 个要过滤的项目,这将是多么昂贵?解开这类代码可能是一场噩梦。
【解决方案2】:

您可以将 TextEdit 的文本属性绑定到 ViewModel 的属性并监视 ViewModel 的该属性(PropertyChanged?!),而不是将 ViewModel 函数绑定到 View 的事件。

只要该属性发生变化,您就可以执行该函数。

通过这种方式,您仍然可以测试 ViewModel,而无需依赖引发的事件将其绑定到 View。

【讨论】:

    【解决方案3】:

    可以通过类似的方式来完成。

    例如:-

    <TextBox Margin="89,116,69,123" x:Name="txtFilter" Background="AliceBlue" >
            <i:Interaction.Triggers>
                <i:EventTrigger EventName="TextChanged">
                    <cmd:EventToCommand Command="{Binding SearchedTextChanged}" CommandParameter="{Binding Text, ElementName=txtFilter}"/>
                </i:EventTrigger>
            </i:Interaction.Triggers>
        </TextBox>
    

    调查

    http://www.c-sharpcorner.com/Blogs/11789/example-of-eventtrigger-in-mvvm-application.aspx http://social.msdn.microsoft.com/Forums/vstudio/en-US/fd819518-605a-46ae-a9e4-26556d0f3e15/wpf-textbox-trigger?forum=wpf

    举个例子。

    【讨论】:

    • 您还需要interaction.dll 才能正常工作。
    【解决方案4】:

    看看下面这篇很好的文章,它清楚地描述了与 EventToCommand 行为的 DevExpress 实现相关的所有方面:DevExpress MVVM Framework. EventToCommand.。 使用这种方法,您可以按如下方式实现您的任务:

    <dxe:TextEdit Margin="89,116,69,123" x:Name="txtFilter" Background="AliceBlue" >
        <dxmvvm:Interaction.Behaviors> 
            <dxmvvm:EventToCommand EventName="EditValueChanged" Command="{Binding FilterCommand}"
                CommandParameter="{Binding ElementName=txtFilter, Path=Text}"/> 
        </dxmvvm:Interaction.Behaviors> 
    ...
    [POCOViewModel]
    public class CoolectionViewModel {
        [Command]
        public void Filter(string searchText) {
            ...
        }
    }
    

    附:使用 DevExpress 控件,您可以通过搜索框完成列表框控件项的过滤,而无需任何编码。只需将ListBoxEdit.FilterCriteria 属性绑定到SearchControl.FilterCriteria 属性即可:

    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition/>
        </Grid.RowDefinitions>
        <dxe:SearchControl x:Name="searchControl" Grid.Row="0" Margin="10"
                         HorizontalAlignment="Stretch" VerticalAlignment="Stretch"/>
        <dxe:ListBoxEdit Name="listBox" Grid.Row="1"  Margin="10"
                         HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
                         DisplayMember="Name" ValueMember="ID"
                         FilterCriteria="{Binding FilterCriteria, ElementName=searchControl}"/>
    </Grid>
    

    您可以使用following demo 使用此方法(链接指向 Silverlight 版本,但 WPF 版本的行为完全相同)。 您可以对 DX 中的任何列表控件(ListBoxEdit、ComboBoxEdit、DXGrid 等)使用相同的方法

    【讨论】:

      猜你喜欢
      • 2014-09-01
      • 2011-04-04
      • 1970-01-01
      • 2012-06-11
      • 2011-11-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多