none
xaml中ListBox显示问题 RRS feed

  • 问题

  • 各位老师。

    xaml片段:

                        <Popup x:Name="indexPopup" Width="240" Placement="{Binding ElementName=IndexTextBox}">
                            <ListBox x:Name="IndexListBox" HorizontalContentAlignment="Stretch"
                                     ItemsSource="{Binding Source={StaticResource IndexListItems}}"
                                     ItemTemplate="{StaticResource IndexItemTemplate}"/>
                        </Popup>
    

    Popup由户通过开关按钮打开或关闭。

    一个很奇怪的现象:

    1、如果一开始就打开Popup,每次ListBox绑定的ItemsSource对象更新后,都会正确同步显示在listBox列表;

    2、如果一开始不打开Popup,经过若干次ListBox绑定的ItemsSource对象更新,然后打开Popup,listBox控件每项显示的都是最后一次的更新内容;

    3、如果一开始不打开Popup,更新绑定数据源过程中打开,打开前列表项不正确;打开后则正确。

    我专门把Popup去掉,只留下ListBox控件。则能同步数据源更新,正确反映在ListBox列表中。

    我的问题是:Popup的打开关闭,真的会影响放在他里面的ListBox吗?有什么解决的办法?

    麻烦各位老师指教。谢谢


    ly_he

    2020年1月10日 11:25

全部回复

  • 各位老师。

    xaml片段:

                        <Popup x:Name="indexPopup" Width="240" Placement="{Binding ElementName=IndexTextBox}">
                            <ListBox x:Name="IndexListBox" HorizontalContentAlignment="Stretch"
                                     ItemsSource="{Binding Source={StaticResource IndexListItems}}"
                                     ItemTemplate="{StaticResource IndexItemTemplate}"/>
                        </Popup>

    Popup由户通过开关按钮打开或关闭。

    一个很奇怪的现象:

    1、如果一开始就打开Popup,每次ListBox绑定的ItemsSource对象更新后,都会正确同步显示在listBox列表;

    2、如果一开始不打开Popup,经过若干次ListBox绑定的ItemsSource对象更新,然后打开Popup,listBox控件每项显示的都是最后一次的更新内容;

    3、如果一开始不打开Popup,更新绑定数据源过程中打开,打开前列表项不正确;打开后则正确。

    我专门把Popup去掉,只留下ListBox控件。则能同步数据源更新,正确反映在ListBox列表中。

    我的问题是:Popup的打开关闭,真的会影响放在他里面的ListBox吗?有什么解决的办法?

    麻烦各位老师指教。谢谢


    ly_he

    我的新思考:

    这可能是因为xaml的UI实现机制:记得看过Josh Smith一篇著名的“Simplifying the WPF TreeView by Using the ViewMode”,告诫人们不要试图通过代码操控UI控件本身。回到我的情况,我想这是因为Popup关闭时,里面的ListBox控件并不存在,直到打开时,WPF才动态创建它。所以使用它和后台交互同步结果自然不对。之所以一开始就打开(情况1)结果正确,也是这个道理。

    我的判断正确与否,请老师指教。



    ly_he

    2020年1月12日 1:15
  • Hi,

    我没有看到你的代码,但是我模仿你的代码写了一个demo,没有你的问题,你看一下

       public partial class MainWindow : Window
        {
            ObservableCollection<string> list1 = new ObservableCollection<string>();
            CollectionViewSource itemCollectionViewSource;
            int i = 4;
    
            public MainWindow()
            {
                InitializeComponent();
                list1.Add("str1");
                list1.Add("str2");
                list1.Add("str3");
                //IndexListBox.ItemsSource = list1;
                itemCollectionViewSource = (CollectionViewSource)FindResource("IndexListItems");
                itemCollectionViewSource.Source = list1;
            }
    
            private void Button_Click(object sender, RoutedEventArgs e)
            {
                
                list1.Add("str" + i.ToString());
                i += 1;
            }
    
            private void Button_Click_1(object sender, RoutedEventArgs e)
            {
                indexPopup.IsOpen = true;
            }
        }
      <Window.Resources>
            <CollectionViewSource x:Key="IndexListItems">
                
            </CollectionViewSource>
        </Window.Resources>
        <StackPanel>
            
            <Popup x:Name="indexPopup" Width="240" Placement="{Binding ElementName=IndexTextBox}" >
                <ListBox x:Name="IndexListBox" HorizontalContentAlignment="Stretch"
                 ItemsSource="{Binding Source={StaticResource IndexListItems}}"                  />
            </Popup>
            <TextBox Name="IndexTextBox" Text="Bottom"/>
            <Button Content="btn1" Click="Button_Click"/>
            <Button Content="btn2" Click="Button_Click_1"/>
        </StackPanel>


    Best Regards,

    Alex


    如果您对Visual Studio 或Microsoft Azure相关产品感兴趣,请点击此链接,或扫描以下二维码注册获取相关信息。



    2020年1月13日 9:45
  • 谢谢Alex,

    我在实际使用这个功能前,也做了几个小样,和您的方式大同小异。但就是放到实际项目中就不行了。后来,我还是在界面上想了办法。就是让Popup一直打开,里面的ListBox通过Visibility的Visible和Collapse操控,算是解决了我的问题。

    非常感谢您的回复和帮助!


    ly_he

    2020年1月16日 10:13