none
Problem with Popup in Listview-DataTemplate

    Question

  • Hello,

    i have a problem, that i cant get a popup working properly in a Listview. I´ve created a TestApp to show and explaim my problem:

     

    <Window x:Class="WpfApplication2.Window1"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      Title="Window1" Height="300" Width="600">
      <Grid>
        <ListView Name="listview">
          <ListView.View>
            <GridView>
              <GridViewColumn Header="Forename" DisplayMemberBinding="{Binding Forename}" Width="100" />
              <GridViewColumn Header="Surname" DisplayMemberBinding="{Binding Surname}" Width="100" />
              <GridViewColumn Header="Age" DisplayMemberBinding="{Binding Age}" Width="100" />
              <GridViewColumn Header="Test" Width="200">
                <GridViewColumn.CellTemplate>
                  <DataTemplate>
                    <TextBlock Text="{Binding Test}" MouseDown="TextBlock_MouseDown"/>
                  </DataTemplate>
                </GridViewColumn.CellTemplate>
              </GridViewColumn>
            </GridView>
          </ListView.View>
        </ListView>
      </Grid>
    </Window>
    
    namespace WpfApplication2
    {
      /// <summary>
      /// Interaktionslogik für Window1.xaml
      /// </summary>
      public partial class Window1 : Window
      {
        public Window1()
        {
          InitializeComponent();
    
          List<DataObject> objects = new List<DataObject>();
          objects.Add(new DataObject() { Age = 25, Forename= "alex", Surname= "s", Test= "test" });
          objects.Add(new DataObject() { Age = 455, Forename = "aaaa", Surname = "bbbb", Test= "teeeest" });
    
          listview.ItemsSource = objects;
        }
    
        private void TextBlock_MouseDown(object sender, MouseButtonEventArgs e)
        {
          if (((TextBlock)sender).Text.Equals("test"))
          {
            PopupTest element = new PopupTest();
    
            element.Placement = PlacementMode.Center;
            element.StaysOpen = false;
            element.PlacementTarget = (UIElement)sender;
            element.IsOpen = true;
          }
          else
          {
            PopupTest element = new PopupTest();
    
            element.Placement = PlacementMode.Center;
            element.StaysOpen = true;
            element.PlacementTarget = (UIElement)sender;
            element.IsOpen = true;
          }
        }
      }
    
      public class DataObject
      {
        public string Forename { get; set; }
        public string Surname { get; set; }
        public int Age { get; set; }
        public string Test { get; set; }
      }
    }
    
    <!-- Popup definition -->
    <Popup x:Class="WpfApplication2.PopupTest"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Height="100" Width="100">
      <TextBox Text="test test test" />
    </Popup>
    
    namespace WpfApplication2
    {
      /// <summary>
      /// Interaktionslogik für ManyToManySelectionElement.xaml
      /// </summary>
      public partial class PopupTest : Popup
      {
        public PopupTest()
        {
          InitializeComponent();
        }
    
        protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e)
        {
          base.OnPropertyChanged(e);
    
          if (e.Property.Equals(PopupTest.IsMouseOverProperty))
          {
            if (IsMouseOver)
            {
              this.StaysOpen = false;
              Debug.WriteLine("this.StaysOpen : " + this.StaysOpen);
            }
          }
        }
      }
    }

    When you start the TestApp there are two rows in the Listview. When you click on 'test'-Text in the first row, there does not happen anything (and thats actually my problem). In codebehind you can see, that i try to open the popup there, but it always closes automatically during this process. When you click on the text of the other row, you can see, that the popup will open, but i can only close it, when i click in it first and thats something i really dont want to do.

    In the popup you can see, that i tried to set the 'Staysopen' property afterwards, but that does not help.

    Does someone have an idea, how i can fix my problem?

    Tuesday, June 29, 2010 6:53 AM

Answers

  • Hi Alexuuus,

    I think it is caused by the list view control, when we click the list view via the left mouse button, the popup control will show firstly, but it will raise a mouse leave event for some reason. But it works ok if you click the control via the right mouse button.

    You can set the StayOpen property as true and then in the mouse leave event, you set the IsOpen property as false.
    Something likes the follows:

    private void TextBlock_MouseDown(object sender, MouseButtonEventArgs e)
    {
        PopupTest test = new PopupTest();
        test.Placement = PlacementMode.Center;
        test.StaysOpen = true;
        test.PlacementTarget = (UIElement)sender;
        test.IsOpen = true;
    }

    public PopupTest()
    {
        InitializeComponent();
        this.MouseLeave += new MouseEventHandler(PopupTest_MouseLeave);
    }

    void PopupTest_MouseLeave(object sender, MouseEventArgs e)
    {
        this.IsOpen = false;
    }


    Hope this helps.

    Best regards,
    Kevin Pan

    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    Monday, July 5, 2010 12:51 PM
    Moderator
  • Hi,

    ok, thanks for your response. Your answer remembered me on a problem i had before and i simply used the "PreviewMousedown"-Event than the normal "MouseDown"-Event. After changing the event, i got the behavior i was looking for. I cant really explain, why it works with it (you probably can do it), but i managed to solve my problem.

    Thanks for your help!

    Best regards,

    alexuuus

    • Marked as answer by alexuuus Monday, July 5, 2010 1:28 PM
    Monday, July 5, 2010 1:28 PM

All replies

  • Hi, Please use this.

    private void TextBlock_MouseDown(object sender, MouseButtonEventArgs e)
        {
          if (((TextBlock)sender).Text.Equals("test"))
          {
            PopupTest element = new PopupTest();

            element.Placement = PlacementMode.Center;
            element.StaysOpen = true;
            element.PlacementTarget = (UIElement)sender;
            element.IsOpen = true;
          }
          else
          {
            PopupTest element = new PopupTest();

            element.Placement = PlacementMode.Center;
            element.StaysOpen = true;
            element.PlacementTarget = (UIElement)sender;
            element.IsOpen = true;
          }
        }
      }


    Syed Mustehsan Ikram
    Tuesday, June 29, 2010 9:44 AM
  • Hi,

    thanks for response, but you dont get my point. I know, how to open the popup, but when i set 'StaysOpen' to true, i can only close the popup when i click in the popup and focus it before. Thats actually not the expected behavior.

    Add in the window something like :

    ....  
    <Grid>
        <Grid.RowDefinitions>
          <RowDefinition Height="25" />
          <RowDefinition Height="*" />
        </Grid.RowDefinitions>
        <TextBlock Grid.Row="0" Text="test" MouseDown="TextBlock_MouseDown" Width="30"/>
        <ListView Grid.Row="1" Name="listview">
    ....

    Then you can see exactly what i mean. When you click on the added Text in the Window, the popup will open and STAY open until you click whereever you want (outside of the popup).

    When you click on the text of the first row, the popup will open, but will automatically close (so it looks like, the popup does not open)...

    ==> so there is a difference between using a popup in a DataTemplate or whereever else. (is there a workaround for that?)

     

    The text in the 2nd row is just to show, that i tried to solve the problem with setting the StaysOpen-Property afterwards...

    Tuesday, June 29, 2010 10:51 AM
  • Hi Alexuuus,

    I  may not understand what the expected behavior you want.

    You can try to add a MouseLeave event to the PopTest class, and set the IsOpen property as false in that event.
    Something likes the follows:

    public PopupTest()

    {

        InitializeComponent();

        this.MouseLeave += new MouseEventHandler(PopupTest_MouseLeave);

    }

     

    void PopupTest_MouseLeave(object sender, MouseEventArgs e)

    {

        this.IsOpen = false;

    }

    Hope this helps.

    Best regards,
    Kevin Pan


    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    Friday, July 2, 2010 10:05 AM
    Moderator
  • Hi,

    sorry, that i haven´t been that clear. To make it clear and simple, take the following modified code:

    <!-- Window-XAML -->
    ...
    <Grid>
        <Grid.RowDefinitions>
          <RowDefinition Height="25" />
          <RowDefinition Height="*" />
        </Grid.RowDefinitions>
        <TextBlock Grid.Row="0" Text="test" MouseDown="TextBlock_MouseDown" Width="30"/>
        <ListView Grid.Row="1" Name="listview">
          <ListView.View>
            <GridView>
              <GridViewColumn Header="Forename" DisplayMemberBinding="{Binding Forename}" Width="100" />
              <GridViewColumn Header="Surname" DisplayMemberBinding="{Binding Surname}" Width="100" />
              <GridViewColumn Header="Age" DisplayMemberBinding="{Binding Age}" Width="100" />
              <GridViewColumn Header="Test" Width="200">
                <GridViewColumn.CellTemplate>
                  <DataTemplate>
                    <TextBlock Text="{Binding Test}" MouseDown="TextBlock_MouseDown"/>
                  </DataTemplate>
                </GridViewColumn.CellTemplate>
              </GridViewColumn>
            </GridView>
          </ListView.View>
        </ListView>
      </Grid>
    ...
    
    <!-- Eventhandler of TextBlock -->
    private void TextBlock_MouseDown(object sender, MouseButtonEventArgs e)
    {
      PopupTest test = new PopupTest();
    
      test.Placement = PlacementMode.Center;
      test.StaysOpen = false;
      test.PlacementTarget = (UIElement)sender;
      test.IsOpen = true;
    }
    
    <!-- Popup -->
    public partial class PopupTest : Popup
    {
      public PopupTest()
      {
       InitializeComponent();
      }
    }

     

    When you create an application with these code-snippets, you will see, that the popup only opens, when you click on the text outside of the listview and thats actually my problem.

    I tried to solve this problem with setting the StaysOpen-Property after the popup has opened, but then i´ve got the problem, that the popup can only be closed, when i focus the popup with my mouse before and that wouldn´t be an expected and favoured behavior of the popup.

    Monday, July 5, 2010 6:48 AM
  • Hi Alexuuus,

    I think it is caused by the list view control, when we click the list view via the left mouse button, the popup control will show firstly, but it will raise a mouse leave event for some reason. But it works ok if you click the control via the right mouse button.

    You can set the StayOpen property as true and then in the mouse leave event, you set the IsOpen property as false.
    Something likes the follows:

    private void TextBlock_MouseDown(object sender, MouseButtonEventArgs e)
    {
        PopupTest test = new PopupTest();
        test.Placement = PlacementMode.Center;
        test.StaysOpen = true;
        test.PlacementTarget = (UIElement)sender;
        test.IsOpen = true;
    }

    public PopupTest()
    {
        InitializeComponent();
        this.MouseLeave += new MouseEventHandler(PopupTest_MouseLeave);
    }

    void PopupTest_MouseLeave(object sender, MouseEventArgs e)
    {
        this.IsOpen = false;
    }


    Hope this helps.

    Best regards,
    Kevin Pan

    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    Monday, July 5, 2010 12:51 PM
    Moderator
  • Hi,

    ok, thanks for your response. Your answer remembered me on a problem i had before and i simply used the "PreviewMousedown"-Event than the normal "MouseDown"-Event. After changing the event, i got the behavior i was looking for. I cant really explain, why it works with it (you probably can do it), but i managed to solve my problem.

    Thanks for your help!

    Best regards,

    alexuuus

    • Marked as answer by alexuuus Monday, July 5, 2010 1:28 PM
    Monday, July 5, 2010 1:28 PM