【问题标题】:Silverlight Chat WrapPanel Crash / BugSilverlight 聊天 WrapPanel 崩溃/错误
【发布时间】:2010-03-30 18:14:19
【问题描述】:

我的任务是为两个人创建一个简单的 Silverlight 聊天框。我的控件必须遵守以下要求

  1. 可滚动
  2. 文本太长必须换行
  3. 添加新项目/消息时,必须将该项目滚动到视图中

现在我已经成功地制作了一个用户控件来满足这些要求,但是我遇到了一个可能的错误/崩溃,我无法在我的生命中修复。我正在寻找解决该错误的方法,或者寻找一种不同的方法来创建可滚动的聊天控件。

这是我一直在使用的代码。我们将从用于聊天窗口的 XAML 开始

<ListBox x:Name="lbChatHistory" Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2" ScrollViewer.VerticalScrollBarVisibility="Visible" ScrollViewer.HorizontalScrollBarVisibility="Disabled" >
    <ListBox.ItemTemplate>
    <DataTemplate>
        <Grid Background="Beige">
        <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="70"></ColumnDefinition>
        <ColumnDefinition Width="Auto"></ColumnDefinition>
        </Grid.ColumnDefinitions>
        <TextBlock x:Name="lblPlayer" Foreground="{Binding ForeColor}"  Text="{Binding Player}" Grid.Column="0"></TextBlock>
        <ContentPresenter Grid.Column="1" Width="200" Content="{Binding Message}" />
    </Grid>
    </DataTemplate>
</ListBox.ItemTemplate>
</ListBox>

这个想法是向列表框添加一个新项目。项目(如 XAML 中所示)是一个简单的 2 列网格。一列用户名,一列消息。

现在我添加到 ListBox 中的“项目”是一个自定义类。它具有我在 XAML 中使用绑定的三个属性(Player、ForeColor 和 Message)

Player 是要显示的当前用户的字符串。

ForeColor 只是一种前景色偏好。它有助于区分消息之间的差异。

MessageWrapPanel。我以编程方式在每个单词的空白处打断提供的字符串。然后对于每个单词,我将一个新的 TextBlock 元素添加到 WrapPanel

这是自定义类。

public class ChatMessage :DependencyObject, INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    public static DependencyProperty PlayerProperty = DependencyProperty.Register( "Player", typeof( string ), typeof( ChatMessage ),
                                                                                         new PropertyMetadata(
                                                                                            new PropertyChangedCallback( OnPlayerPropertyChanged ) ) );

    public static DependencyProperty MessageProperty = DependencyProperty.Register( "Message", typeof( WrapPanel ), typeof( ChatMessage ),
                                                                                         new PropertyMetadata(
                                                                                            new PropertyChangedCallback( OnMessagePropertyChanged ) ) );

    public static DependencyProperty ForeColorProperty = DependencyProperty.Register( "ForeColor", typeof( SolidColorBrush ), typeof( ChatMessage ),
                                                                                         new PropertyMetadata(
                                                                                            new PropertyChangedCallback( OnForeColorPropertyChanged ) ) );

    private static void OnForeColorPropertyChanged( DependencyObject d, DependencyPropertyChangedEventArgs e )
    {
        ChatMessage c = d as ChatMessage;
        c.ForeColor = ( SolidColorBrush ) e.NewValue;
    }

    public ChatMessage()
    {
        Message = new WrapPanel();
        ForeColor = new SolidColorBrush( Colors.White );
    }

    private static void OnMessagePropertyChanged( DependencyObject d, DependencyPropertyChangedEventArgs e )
    {
        ChatMessage c = d as ChatMessage;
        c.Message = ( WrapPanel ) e.NewValue;
    }

    private static void OnPlayerPropertyChanged( DependencyObject d, DependencyPropertyChangedEventArgs e )
    {
        ChatMessage c = d as ChatMessage;
        c.Player = e.NewValue.ToString();
    }

    public SolidColorBrush ForeColor
    {
        get { return ( SolidColorBrush ) GetValue( ForeColorProperty ); }
        set
        {
            SetValue( ForeColorProperty, value );
            if(PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs( "ForeColor" ));
        }
    }

    public string Player
    {
        get { return ( string ) GetValue( PlayerProperty ); }
        set
        {
            SetValue( PlayerProperty, value );
            if ( PropertyChanged != null )
                PropertyChanged( this, new PropertyChangedEventArgs( "Player" ) );
        }
    }

    public WrapPanel Message
    {
        get { return ( WrapPanel ) GetValue( MessageProperty ); }
        set
        {
            SetValue( MessageProperty, value );
            if ( PropertyChanged != null )
                PropertyChanged( this, new PropertyChangedEventArgs( "Message" ) );
        }
    }
}

最后,我将我的项目添加到 ListBox。这是简单的方法。它将上面的 ChatMessage 类作为参数

public void AddChatItem( ChatMessage msg )
    {
        lbChatHistory.Items.Add( msg );
        lbChatHistory.ScrollIntoView( msg );
    }

现在我已经对此进行了测试,并且一切正常。我遇到的问题是当我使用滚动条时。您可以使用侧滚动条或箭头键向下滚动,但向上滚动时 Silverlight 会崩溃。 FireBug 返回带有 XamlParseExceptionManagedRuntimeError #4004

我已经快要完成这个控制工作了,我可以尝尝!对我应该做什么或改变有什么想法吗?有没有比我采用的方法更好的方法?

提前致谢。

更新

我找到了使用 ScrollViewer 和 ItemsControl 而不是 ListBox 控件的替代解决方案。大多数情况下它是稳定的。

【问题讨论】:

    标签: silverlight wrappanel chatroom


    【解决方案1】:

    我找到了使用 ScrollViewer 和 ItemsControl 而不是 ListBox 控件的替代解决方案。大多数情况下它是稳定的。

    这是我现在使用的 XAML。

    <ScrollViewer x:Name="lbChatHistoryScroller">
                        <ItemsControl x:Name="lbChatHistory" Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2" ScrollViewer.VerticalScrollBarVisibility="Visible" ScrollViewer.HorizontalScrollBarVisibility="Disabled">
                            <ItemsControl.ItemTemplate>
                                <DataTemplate>
                                    <Grid Background="Beige">
                                        <Grid.ColumnDefinitions>
                                            <ColumnDefinition Width="70"></ColumnDefinition>
                                            <ColumnDefinition Width="Auto"></ColumnDefinition>
                                        </Grid.ColumnDefinitions>
                                        <TextBlock x:Name="lblPlayer" Foreground="{Binding ForeColor}" Text="{Binding Player}" Grid.Column="0"></TextBlock>
                                        <ContentPresenter Grid.Column="1" Width="1750" Content="{Binding Message}">
                                        </ContentPresenter>
                                    </Grid>
                                </DataTemplate>
                            </ItemsControl.ItemTemplate>
                        </ItemsControl>
                    </ScrollViewer>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-05-31
      • 2010-12-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多