【问题标题】:problem with listbox data template and visible state列表框数据模板和可见状态的问题
【发布时间】:2011-06-02 19:39:17
【问题描述】:

我有一个列表框,其中用户控件设置为列表框项。在这个列表框中,我有几个网格和两个按钮。

<Grid x:Name="LayoutRoot" HorizontalAlignment="Stretch">
    <Grid.RowDefinitions>
        <RowDefinition Height="120" />
        <RowDefinition x:Name="personDetailHolder" Height="*" />
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="92.915" />
        <ColumnDefinition />
    </Grid.ColumnDefinitions>
    <StackPanel Grid.RowSpan="2"
                Grid.ColumnSpan="2"
                Margin="0,0,-0.042,0"
                Orientation="Vertical"
                d:LayoutOverrides="Height">
        <Grid Height="117" Margin="3,0,0,0">
            <Grid.RowDefinitions>
                <RowDefinition Height="117" />
                <RowDefinition Height="*" />
            </Grid.RowDefinitions>
            <Rectangle  />
            <!-- removed for brevity -->

            <Button x:Name="btnViewDetails"
                    Width="106"
                    Height="24"
                    Margin="0,0,3,6"
                    HorizontalAlignment="Right"
                    VerticalAlignment="Bottom"
                    Click="btnDetails_Click"
                    Foreground="#FFFBCE2F"
                    Style="{StaticResource ViewDetailsButton}" />
            <!--  Detail section  -->
            <Grid x:Name="personDetail"
                  Grid.Row="1"
                  MinHeight="365"
                  Margin="0,0,5,-376"
                  VerticalAlignment="Bottom"
                  RenderTransformOrigin="0.5,0.5"
                  Visibility="Collapsed">
                <Rectangle />
                <!--  removed for brevity -->   

                <Button x:Name="btnCloseDetails"
                        Width="123"
                        Height="24"
                        Margin="0,8,8,0"
                        HorizontalAlignment="Right"
                        VerticalAlignment="Top"
                        Click="btnDetails_Click"
                        Foreground="#FFFBC42F"
                        Style="{StaticResource CloseDetailsButton}" />

            </Grid>
        </Grid>
    </StackPanel>
</Grid>

点击事件btnDetails_Click在用户控件后面的代码中调用一个事件

private void btnDetails_Click(object sender, System.Windows.RoutedEventArgs e)
{
    UIPanelControl cp = new UIPanelControl();
    cp.CheckDetailPanelStatus(this.personDetail, this.personDetailHolder, this.btnViewDetails, this.btnCloseDetails, this.detailAnimation);
}

调用方法

public void CheckDetailPanelStatus(Grid panelName, RowDefinition rowName, Button openButtonName, Button closeButtonName, Storyboard animi)
{
    if (panelName.Visibility == System.Windows.Visibility.Visible)
    {
        panelName.Visibility = System.Windows.Visibility.Collapsed;
        rowName.Height = new GridLength(0);
        openButtonName.Visibility = System.Windows.Visibility.Visible;
        closeButtonName.Visibility = System.Windows.Visibility.Collapsed;
    }
    else
    {
        panelName.Visibility = System.Windows.Visibility.Visible;
        rowName.Height = new GridLength(380);
        openButtonName.Visibility = System.Windows.Visibility.Collapsed;
        closeButtonName.Visibility = System.Windows.Visibility.Visible;
        animi.Begin();

    }
}

这里的目标是向用户返回结果列表。然后,用户可以单击查看其他详细信息按钮展开第二部分,该部分显示有关所选记录的更多详细信息。我正在使用 MVVM 方法,因此命令转到 VM 以促进第二个记录填充。由于动画、可见性等都包含在视图中,因此我决定将这些事件保留在视图代码中。

此解决方案部分有效,因为当我单击按钮时,该部分确实会针对选定的列表框项展开。但是,如果我向下滚动到其他结果,我会发现其他列表框项目会间歇性地扩展。这没有可重复的模式(即每 5 个项目或每隔一个记录)而且我还看到了如果我选择第一个记录并展开它然后向下滚动到下一个记录并备份第一个记录已被重置的实例折叠起来。

我对可能导致此问题的原因感到困惑。

谁能提供我看到这种情况发生的原因或如何防止这种情况发生的任何见解?

【问题讨论】:

    标签: silverlight mvvm datatemplate listboxitem


    【解决方案1】:

    您看到的是列表框使用对象重用来节省内存和提高性能的结果,类似的事情也可能发生在 GridView 中。控件所做的是创建 X ListBoxItems 并在它们的数据项超出视图(加载/卸载)时重用这些容器。所以如果你改变容器的外观,它会改变所有共享容器的数据项的外观。

    要解决此问题,您可以: 处理 ListBoxItem 的 Loaded/Unloaded 事件并在 Unloaded 事件触发时修复 UI。 或者,让您绑定到 List Selection 的项目知道并让它们更改 ListBoxItem 外观,因此当它们被加载/卸载时,绑定引擎将负责重置 UI。

    【讨论】:

    • 阿吉斯。感谢您解释如何重用对象。我对对象的加载/卸载一无所知。你真的帮助我指明了正确的方向,谢谢!
    【解决方案2】:

    我认为这可以更好地使用 VisualStates 来实现,而不是在点击事件上手动设置属性。

    只需在列表项的模板中添加两种视觉状态,一种用于“ShowDetails”,一种用于“HideDetails”。然后,您可以使用行为GoToVisualStateBehavior 在单击按钮时在它们之间切换(我认为应该是ToggleButton)。

    否则,您可以使用Expander 按钮来实现此功能。

    希望这会有所帮助:)

    【讨论】:

    • AbdouMomen,非常感谢您的指点。我尝试了视觉状态和扩展器,似乎都解决了这个问题。为简单起见,我使用了扩展器元素,但将来我肯定会使用 VisualStateBehavior。
    【解决方案3】:

    而不是用命令改变可见性

    panelName.Visibility = System.Windows.Visibility.Collapsed;
    

    您想将 xaml 中的可见性设置为类似

        <Grid x:Name="personDetail"
              Grid.Row="1"
              MinHeight="365"
              Margin="0,0,5,-376"
              VerticalAlignment="Bottom"
              RenderTransformOrigin="0.5,0.5"
              Visibility="{Binding PersonDetailVisibility}">
    

    假设您将属性更改的事件处理程序连接到以下内容:

            PropertyChanged += new
            PropertyChangedEventHandler(PersonDetailViewModel_PropertyChanged);
    

    然后在VM中更改您的PersonDetailVisibility属性后,您需要引发属性更改事件

                this.RaisePropertyChanged(() => this.PersonDetailVisibility);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多