我有一个绑定到ObservableCollection ProductsFound的DataGrid 它在我的ViewModel中作为属性公开。 通过在TextBox中键入文本,模型中包含的包含TextBox中插入的文本的Code属性的产品将添加到ProductsFound。
我发现如果DataGrid包含在任何控件(如StackPanel或TabItem)中,当我尝试在TextBox中键入文本时,Window(程序)会停止响应;如果DataGrid未包含在任何控件中,则一切都正常运行。
这是窗口的代码:
public class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
// This method just fill the dataset I pass to the model's contructor in the next line.
Init();
ProductsModel model = new ProductsModel(dataSet);
searchViewModel = new ProductsSearchViewModel(model);
DataContext = searchViewModel;
}
private ProductsSearchViewModel searchViewModel;
// This handler supports the binding between the TextBox and the MatchText property of the View Model.
private void TextBox_TextChanged(object sender, TextChangedEventArgs e)
{
var binding = ((TextBox)sender).GetBindingExpression(TextBox.TextProperty);
binding.UpdateSource();
}
}
这是我的ViewModel:
public class ProductsSearchViewModel : Notifier, IProductsSearchViewModel
{
public ProductsSearchViewModel(IProductsModel inModel)
{
model = inModel;
productsFound = new ObservableCollection<ProductViewModel>();
}
private string matchText;
private IProductsModel model;
private ObservableCollection<ProductViewModel> productsFound;
// This is a helper method that search for the products in the model and adds them to ProductsFound.
private void Search(string text)
{
Results.Clear();
foreach (Product product in model.Products)
{
if (product.Code.ToLower().Contains(text.ToLower()))
Results.Add(new ProductViewModel(product));
}
}
public string MatchText
{
get { return matchText; }
// This setter is meant to be executed every time the Text property of the TextBox is changed.
set
{
if ((value != matchText) && (value != ""))
{
matchText = value;
// This raises INotifyPropertyChanged.PropertyChaged.
NotifyPropertyChanged("MatchText");
Search(value);
}
}
}
public ObservableCollection<ProductViewModel> ProductsFound
{
get
{
return productsFound;
}
set
{
productsFound = value;
NotifyPropertyChanged("Results");
}
}
}
这是XAML:
<Window x:Class="MyNameSpace.UI.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<StackPanel>
<TextBox Text="{Binding MatchText, Mode=TwoWay}" TextChanged="TextBox_TextChanged" />
<DataGrid x:Name="grid1" ItemsSource="{Binding Results}" >
</StackPanel>
</Grid>
使用该StackPanel,当我尝试在文本框中键入文本并且没有任何项添加到DataGrid时程序停止响应;但如果我删除它一切都运行正常。 问题是什么?我是否遗漏了WPF绑定系统的工作原理? 我的视图模型编码错了吗?
提前致谢。
答案 0 :(得分:2)
将StackPanel
放在那里会阻止DataGrid
获取特定的Height
,因此它会向下扩展到无穷大,从而打破了UI虚拟化。
从那里移除StackPanel
并使用非无限容器,例如Grid
或DockPanel
。