2010-03-30 68 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>