简体   繁体   中英

WPF MVVM: binding command to event

I have my view and viewmodel files. In my viewmodel, I have this simply code:

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

In my xaml I have:

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

DUMB QUESTION: how can I bind my function to the event EditValueChanged, passing also like parameter the content of the textbox? the simply goal is: when the user writes something in the textbox, filter the collection binded to the viewmodel.

Online I have found a lot of tutorial, code snippet and so on, but anyone of these is helping me to understand.

it can be done with something similar to this.

Eg:-

<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>

look into

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

for further example.

Take a look at the following good article that clearly describes all the aspects related to the DevExpress implementation of the EventToCommand behavior: DevExpress MVVM Framework. EventToCommand. . With using this approach you can implement your task as follows:

<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) {
        ...
    }
}

PS Using the DevExpress controls you can accomplish the filtering of the listbox-control items via search-box without any coding at all. Just bind the ListBoxEdit.FilterCriteria property to the SearchControl.FilterCriteria property:

<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>

You can play with this approach using the following demo (the link points to the Silverlight version, but the WPF version behaves exactly the same). You can use the same approach with any list-control from DX (ListBoxEdit, ComboBoxEdit, DXGrid etc.)

Instead of binding the ViewModel function to the event of the View you could bind the TextEdit's text property to a property of the ViewModel and monitor that property of the ViewModel (PropertyChanged?!).

As soon as that property changes you could execute the function.

This way you can still test the ViewModel without tying it to the View by relying to the raised event.

Your TextEdit control should be bound to a property in the ViewModel. In the setter of that property you would call the Filter method.

This example with the assumption that your TextEdit control has a Text property. If not, change to bind to whatever the property name is.

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

Then in the ViewModel class:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM