Autocomplete TextBox that follows the MVVM pattern

I have a text box and I want to make it an autocomplete text box. The data I'm going to show when I type a text box is in my datagrid. My datagrid has 4 columns, and I can select any column from the datagrid.

Here is my text box

<TextBox Margin="0,93,39,18" Grid.Column="1" HorizontalAlignment="Right" Width="325"> <TextBox.Style> <Style TargetType="TextBox"> <Style.Triggers> <Trigger Property="Text" Value=""> <Setter Property="Background" Value="{StaticResource SearchHint}"/> </Trigger> </Style.Triggers> </Style> </TextBox.Style> </TextBox> 

DataGrid

  <DataGrid Name="Datagrid" ItemsSource="{Binding Messages}" Margin="4,0,380,413" Grid.Row="1" AutoGenerateColumns="False" IsReadOnly="True" RowBackground="WhiteSmoke" > 

I am googled and most of the samples I received do not match the WPF / MVVM pattern. What I'm going to do is bind the text block data to the grid elements. Can someone help me by telling me where to start.

+6
source share
1 answer

There are many different ways to approach this question, but perhaps the most noticeable is the combobox editable strategy (they ask a lot of questions about this in the Microsoft WPF exam, completely ignoring the MVVM pattern, but this is a problem for another day). I will give an example to get you started. The first step is to create code with a list and datagrid ...

  <StackPanel> <ComboBox IsEditable="True" IsTextSearchEnabled="True" IsSynchronizedWithCurrentItem="True" SelectedItem="{Binding MySelectedItem, Mode=TwoWay}" ItemsSource="{Binding MyItems}" > <ComboBox.InputBindings> <KeyBinding Key="Enter" Command="{Binding NotImplementedCommand}"/> </ComboBox.InputBindings> </ComboBox> <DataGrid ItemsSource="{Binding DriveList}" AutoGenerateColumns="True" /> </StackPanel> 

And then create a ViewModel ...

 public class ViewModel :INotifyPropertyChanged { public ObservableCollection<string> MyItems { get; set; } public ObservableCollection<DriveInfo> DriveList { get; set; } public event PropertyChangedEventHandler PropertyChanged; public ViewModel() { MyItems = new ObservableCollection<string>(); DriveList = new ObservableCollection<DriveInfo>(); foreach (DriveInfo di in DriveInfo.GetDrives()) { DriveList.Add(di); } DriveListCollectionChanged(null, null); DriveList.CollectionChanged += DriveListCollectionChanged; } void DriveListCollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e) { MyItems.Clear(); List<string> temp = new List<string>(); foreach (DriveInfo di in DriveList) {// add 4 columns from the DataGrid to the auto complete source temp.Add(di.Name); temp.Add(di.DriveType.ToString()); if (di.IsReady) { temp.Add(di.DriveFormat); temp.Add(di.TotalSize.ToString()); temp.Add(di.AvailableFreeSpace.ToString()); } } foreach (string s in temp.Distinct()) { MyItems.Add(s); } } private string _mySelectedItem; public string MySelectedItem { get { return _mySelectedItem; } set { if (value != _mySelectedItem) { _mySelectedItem = value; OnPropertyChanged("MySelectedItem"); } } } private void OnPropertyChanged(string s) { if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(s)); } } } 

In this example, an event is interrupted in which the DataGrid source changes and fills the combo box using the MULTIPLE columns. If you were to make only one column, the solution here would be different. There is also some esoterica binding where you can automatically bind the combobox to data, but its didactic value is doubtful, given what you asked, and your intention to add several columns of dissimilar rows in the drop-down field.

You will need to better optimize the event handler before deploying the application, because the one shown above is for demonstration purposes only.

To link this, put this (or its alternative) in your Haml ...

  <Window.Resources> <wpfApplication3:ViewModel x:Key="ViewModel"/> </Window.Resources> <Grid DataContext="{StaticResource ViewModel}"> <!-- your xaml --> </Grid> 

The ViewModel class above is an MVVM compatible solution, and you bind an instance of this class to the DataContext of the view.

+8
source

Source: https://habr.com/ru/post/947746/


All Articles