나는 두 사람의 간단한 Silverlight 대화방을 만드는 작업을했습니다. 내 컨트롤이 너무 오래 있다면 Silverlight 채팅 WrapPanel 충돌/버그
- 스크롤 다음과 같은 요구 사항을 준수해야합니다
- 새 항목/메시지는
지금보기에 그 항목을 스크롤합니다 추가 될 때 나는 이러한 요구 사항을 충족하기 위해 성공적으로 usercontrol을 만들었지 만 가능한 버그/충돌에 직면했습니다. 나는 버그를 수정하거나 스크롤 가능한 채팅 컨트롤을 만드는 다른 접근법을 찾고있다.
다음은 내가 사용 해본 코드입니다. 채팅 창에 대한 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>
아이디어는 목록 상자에 새 항목을 추가하는 것입니다. Item (XAML에 레이아웃 된대로)은 간단한 2 열 그리드입니다. 사용자 이름에 대해 하나의 열과 메시지에 대해 하나의 열.
이제 ListBox에 추가하는 "항목"이 사용자 지정 클래스입니다. XAML 내에서 바인딩을 사용하는 세 가지 속성 (Player, ForeColor 및 Message)이 있습니다.
플레이어은 표시 할 현재 사용자의 문자열입니다.
ForeColor은 전경색 선호도입니다. 그것은 메시지의 차이를 구별하는 데 도움이됩니다.
메시지은 WrapPanel입니다. 프로그래밍 방식으로 공백에 제공된 문자열을 각 단어에 나누십시오. 그런 다음 각 단어에 대해, 나는 여기에 WrapPanel
에 새 TextBlock의 요소를 추가 사용자 정의 클래스입니다.
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는 ManagedRuntimeError # 4004을 XamlParseException으로 반환합니다.
나는이 제어 작업을하는 것에 가까워서 맛볼 수있다! 내가해야 할 일이나 변경해야 할 일에 대한 생각? 제가 택한 것보다 더 좋은 접근법이 있습니까?
미리 감사드립니다.
UPDATE는
전에서 ScrollViewer와 ItemsControl을 대신 ListBox 컨트롤을 사용하여 대체 솔루션을 발견했습니다. 대부분 안정적입니다.