通过IValueConverter将Popup.IsOpen绑定到ObservableCollection时丢失绑定/对象引用

时间:2017-04-01 18:00:50

标签: c# wpf binding popup

目前我正在尝试通过IValueConverter将Popup.IsOpen属性绑定到ObservableCollection,确定集合是否包含项目(true)或不是(false)。

问题: IValueConverter仅在初始化应用程序时触发一次,然后再也不会再触发。

查看:

<UserControl x:Class="AutoCompleteTextBox.Views.AutoCompleteTextBoxView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:AutoCompleteTextBox.Views"
             xmlns:converter="clr-namespace:AutoCompleteTextBox.Converter"
             xmlns:viewmodels="clr-namespace:AutoCompleteTextBox.ViewModels"
             mc:Ignorable="d"
             d:DesignHeight="300" d:DesignWidth="300">
    <UserControl.Resources>
        <converter:CollectionHasItemsToBooleanConverter x:Key="collectionHasItemsToBoolean" />
    </UserControl.Resources>

    <UserControl.DataContext>
        <viewmodels:AutoCompleteTextBoxViewModel />
    </UserControl.DataContext>
    <Grid>
        <TextBox 
            Name="txtSearchBox"            
            Text="{Binding SearchString,UpdateSourceTrigger=PropertyChanged,Mode=OneWayToSource}" />
        <Popup 
            IsOpen="{Binding UserCollection,
            Converter={StaticResource collectionHasItemsToBoolean},UpdateSourceTrigger=PropertyChanged,Mode=TwoWay}"
            Width="{Binding ElementName=txtSearchBox,Path=ActualWidth}"
            PlacementTarget="{Binding ElementName=txtSearchBox}">
            <ListView 
                ItemsSource="{Binding UserCollection,UpdateSourceTrigger=PropertyChanged,Mode=OneWay}">
                <ListView.ItemTemplate>
                    <DataTemplate>
                        <Label Content="{Binding Name,UpdateSourceTrigger=PropertyChanged,Mode=OneWay}">
                        </Label>
                    </DataTemplate>
                </ListView.ItemTemplate>
            </ListView>
        </Popup>
    </Grid>
</UserControl>

视图模型:

public class AutoCompleteTextBoxViewModel : BindableBase
{
    private string searchString;

    public string SearchString
    {
        get { return searchString; }
        set
        {
            if (SetProperty(ref searchString, value))
            {
                if (UserCollection.Count == 3) UserCollection.Clear();
                if (searchString != string.Empty)
                {
                    UserCollection.Add(new UserModel() { Name = DateTime.Now.ToLongTimeString() });
                }
            }
        }
    }

    public ObservableCollection<UserModel> UserCollection { get; set; }
    public AutoCompleteTextBoxViewModel()
    {
        UserCollection = new ObservableCollection<UserModel>();            
    }
}

详细说明: BindableBase类实现INotifyPropertChanged,通过在属性的setter中使用SetProperty来触发。 手动将PopUp.IsOpen设置为true时,所需的弹出窗口正在工作。 将PopUp.IsOpen绑定到ObservableCollection.Count(使用自定义的IValueConverter检查int值)。

有没有人看到我目前缺少的错误或一些提示?

周末愉快!

丹尼尔

1 个答案:

答案 0 :(得分:0)

CrudaLilium的评论工作:

“我认为问题在于,当您对UserCollection进行更改时,只会触发CollectionChanged并且此触发器不会触发更新。您必须从VM中激活带有UserCollection名称的PropertyChanged才能触发它。”