wpf 遵循 MVVM 模式的自动完成文本框
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/17217241/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Autocomplete TextBox that follows MVVM pattern
提问by Ayda Sayed
I have a textbox and I want to make it an autocomplete text box. The data I am going to show when I type the textbox is from my datagrid. My datagrid has 4 columns and I can pick any column from the datagrid.
我有一个文本框,我想让它成为一个自动完成的文本框。当我输入文本框时,我将显示的数据来自我的数据网格。我的数据网格有 4 列,我可以从数据网格中选择任何列。
Here is my textbox
这是我的文本框
<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 googled and most of the samples I got doesn't follow WPF/MVVM pattern. What I am about to do is bind the textblock data to the grid items.Can someone help me by giving me points on where to start.
我用谷歌搜索,我得到的大多数样本都没有遵循 WPF/MVVM 模式。我要做的是将文本块数据绑定到网格项。有人可以帮我指出从哪里开始。
回答by Gayot Fow
There are lots of different ways to approach this question, but arguably the most prominent is the editable combobox strategy (they ask a lot of questions about this in Microsoft's WPF exam which totally IGNORE the MVVM pattern, but that's an issue for another day). I'll give an example to get you started. The first step is to code up a combobox and datagrid...
有很多不同的方法来解决这个问题,但可以说最突出的是可编辑的组合框策略(他们在微软的 WPF 考试中提出了很多关于这个问题的问题,完全忽略了 MVVM 模式,但这是另一天的问题)。我会举一个例子来帮助你入门。第一步是编写组合框和数据网格...
<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...
然后创建一个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));
}
}
}
This example interrupts the event where the DataGrid's source is changed and populates the combo box with MULTIPLE columns. If you were just doing a single column, the solution here would vary. There is also some binding esoterica where you can automatically bind the combobox to the data, but its didactic value is questionable given what you have asked and your intent to add multiple columns of heterogeneous strings to a combobox.
此示例中断 DataGrid 源更改的事件,并使用 MULTIPLE 列填充组合框。如果你只做一个列,这里的解决方案会有所不同。还有一些绑定秘诀,您可以在其中自动将组合框绑定到数据,但鉴于您的要求以及将多列异构字符串添加到组合框的意图,其教学价值值得怀疑。
You'll need to better optimize the event handler before deploying your app because the one shown above is only for demonstration purposes.
在部署应用程序之前,您需要更好地优化事件处理程序,因为上面显示的仅用于演示目的。
To wire this up, put this (or its alternate) in your Xaml...
要将其连接起来,请将它(或其替代品)放入您的 Xaml 中...
<Window.Resources>
<wpfApplication3:ViewModel x:Key="ViewModel"/>
</Window.Resources>
<Grid DataContext="{StaticResource ViewModel}">
<!-- your xaml -->
</Grid>
The ViewModel class above is an MVVM compliant solution, and you would bind an instance of this class to the DataContext of the presenting view.
上面的 ViewModel 类是符合 MVVM 的解决方案,您可以将此类的实例绑定到呈现视图的 DataContext。

