2010-03-30 73 views
0

我已经被赋予创建两个人的简单Silverlight聊天框的任务。我的控制必须符合以下要求Silverlight Chat WrapPanel崩溃/错误

  1. 滚动,如果它太长
  2. 文本必须包裹
  3. 当添加一个新的项目/信息必须滚动该项目进入视野现在

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

这是我一直在使用的代码。我们将从我的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只是一个前景色偏好。它有助于区分消息之间的差异。

消息WrapPanel。我编程打破提供的字符串的空白空间为每个单词。然后,每个字,我一个新的的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")); 
     } 
    } 
} 

最后,我将我的项目添加到列表框中。这是简单的方法。它需要上面的ChatMessage类作为参数

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

现在我测试了这一切,它的一切工作。我得到的问题是当我使用滚动条。您可以使用侧滚动条或箭头键向下滚动,但是当您向上滚动Silverlight崩溃时。 FireBug返回ManagedRuntimeError#4004XamlParseException

我很接近有这个控制工作,我可以品尝它!关于我应该做什么或改变什么的想法?有没有比我采取的更好的方法?

在此先感谢。

UPDATE

我发现使用的ScrollViewer和一个ItemsControl代替列表框控件的替代解决方案。大多数情况下它很稳定。

回答

0

我发现了一个使用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>