我正在开发一个MVVM WPF应用程序,其中一个请求的功能是一个自动完成框,可以过滤一系列项目,允许用户开始输入项目以快速查找并选择正确的项目,这是使用autocompletebox相对容易。
但是,还需要检测用户何时键入无现有项目,然后创建该项目。但是,我在确定如何检测用户何时输入与项目不匹配的文字时遇到问题。
我尝试绑定到text属性并在autocompletebox失去焦点时触发事件,然后检查是否设置了selected属性,如果不使用该文本来创建新项目。但是,如果用户输入文本,选择和项目,然后将文本更改为无现有项目,则会导致问题。 这导致SelectedItem被设置,Text被设置为新的。
所以我追求的是:
看起来像应该非常明显/容易的东西,因为我想这远非罕见,但是我还没有看到这样做的合理方式,不需要黑客代码或编写自定义自动完成框,我如果有人知道可以实现这一点的现有控制,或者想要做到这一点的方法,我宁愿避免这样做。
根据要求,这是我使用的代码。
查看代码:
<Utils:AutoCompleteFocusableBox MaxWidth="200" Grid.Row="2" Grid.Column="1" Grid.ColumnSpan="5"
ItemsSource="{Binding ItemsList}"
IsTextCompletionEnabled="True"
FilterMode="Contains"
x:Name="ACBox"
LostFocus="ACBox_LostFocus"
Text="{Binding ItemText, Mode=TwoWay, UpdateSourceTrigger=LostFocus}"
SelectedItem="{Binding ItemInfo, Mode=TwoWay, UpdateSourceTrigger=LostFocus}"/>
查看背后的代码:
private void ACBox_LostFocus(object sender, RoutedEventArgs e)
{
AutoCompleteFocusableBox box = sender as AutoCompleteFocusableBox;
if (!String.IsNullOrEmpty(box.SearchText))
{
string text = box.SearchText;
IEventAggregator eventAggregator = IoC.Get<IEventAggregator>();
eventAggregator.Publish(new SearchTextEvent(text));
}
}
ViewModel代码:
public string ItemText
{
get { return _itemText; }
set
{
_itemText = value;
NotifyOfPropertyChange(() => ItemText);
}
}
public ItemInfo ItemInfo
{
get { return _itemInfo; }
set
{
if(_itemInfo != value)
{
_itemInfo = value;
NotifyOfPropertyChange(() => ItemInfo);
}
}
}
ViewModel中的事件处理程序,以及检查项目的方法。
public void Handle(SearchTextEvent message)
{
CheckItem(message.Text);
}
private void CheckItem(string itemName)
{
if (ItemInfo == null)
{
if (ItemsList.Where(x => x.ItemName == itemName).Count() < 1)
{
ItemInfo = new ItemInfo(0, itemName, null);
NewItemVisibility = Visibility.Visible;
}
else
{
NewItemVisibility = Visibility.Hidden;
ItemInfo ii = ItemRepository.GetItemByName(itemName);
ItemInfo = ii;
}
}
else
{
}
}