Search code examples
c#wpfpopupicommandrelaycommand

Open a WPF Popup with a button


I'm trying to open a Popup with a button and have implemented a basic ICommand. The button is binded to the ICommand OpenPopupCommand while the Popup IsOpen attribute is binded to the "IsOpen" OnPropertyChanged. My thought process was to bind the Popup.IsOpen attribute to the ICommand as well to have IT trigger the OnPropertyChange but couldn't get it to work. I think I'm close but can't figure it out. Here is the code I have so far:

    #region ICommand Members

    private ICommand _openPopupCommand;
    public ICommand OpenPopupCommand
    {
        get
        {
            if (_openPopupCommand == null)
                _openPopupCommand = new RelayCommand(param => OpenPopupExecute(param));
            return _openPopupCommand;
        }
        set 
        {
            _openPopupCommand = value;
        }
    }

    #endregion

    #region Methods

    public void OpenPopupExecute(object parameter)
    {
        parameter = true;
        OnPropertyChanged("IsOpen");
    }

    #endregion

Button that "pops up" the Popup and the Popup XAML:

<Popup x:Name="FieldsPopup" Placement="Center" Width="400" Height="250" IsOpen="{Binding IsOpen}">
                    <StackPanel>
                        <TextBlock Background="LightBlue" HorizontalAlignment="Center" VerticalAlignment="Center" Height="250" Width="350" TextAlignment="Center" >This is a popup</TextBlock>
                    </StackPanel>
                </Popup>
<Button Name="button_PatientIdentifierList" Width="23" Height="23" Grid.Column="2" Foreground="Black" Background="#FFCDCDCD" BorderBrush="#FF707070" Margin="3.4,4,4,0" VerticalAlignment="Top" Command="{Binding OpenPopupCommand}"/>

Solution

  • You're raising the PropertyChange notification, but I don't see you actually changing the property anywhere.

    Unless I'm mistaken, this code here takes the CommandParameter (called parameter here) and sets it to true

    public void OpenPopupExecute(object parameter)
    {
        parameter = true;
        OnPropertyChanged("IsOpen");
    }
    

    However in your XAML the Button.CommandParameter isn't bound to anything

    <Button Command="{Binding OpenPopupCommand}"/>
    

    So I suspect that parameter is just null, and is not actually doing anything here.

    What you seem to be missing is the actual IsOpen property definition, and setting it to true in your command's Execute code :

    private bool _isOpen;
    public bool IsOpen
    {
        get
        {
            return _isOpen;
        }
        set 
        {
            _isOpen = value;
            OnPropertyChanged("IsOpen");
        }
    }
    
    public void OpenPopupExecute(object parameter)
    {
        IsOpen = true; // Will call OnPropertyChanged in setter
    }
    

    As a side note, I really don't like WPF's default PopupControl, and have a custom UserControl version of it on my blog if you ever decide you hate WPF's default PopupControl too :)