我在ListView的DataTemplate中有一个RichTextBox控件。我的想法是,我想在绑定时动态地将运行/内联元素/图像等添加到Listview中的富文本框。问题是没有ondatabinding或类似的事件。我尝试了RichTextBox的Loaded事件,但看起来WPF重用了控件,所以当我滚动时内容被弄乱(错误的内容输入错误,因为加载事件在滚动期间触发)。我还应该提到通过手动向ListView.Items集合添加行,在代码隐藏中对ListView进行绑定。
相关标记
<ListView Background="#F7F7F7" HorizontalAlignment="Stretch" Foreground="Black" x:Name="chatPane" Grid.Row="1"
ScrollViewer.HorizontalScrollBarVisibility="Disabled" HorizontalContentAlignment="Stretch" SelectionMode="Multiple"
ItemTemplateSelector="{StaticResource messageTypeDataTemplateSelector}" SelectionChanged="ChatPane_OnSelectionChanged">
</ListView>
<common:MessageTypeDataTemplateSelector
TextMessageTemplate="{StaticResource TextMessage}"
EnterMessageTemplate="{StaticResource EnterMessage}"
ExitMessageTemplate="{StaticResource ExitMessage}"
TimestampMessageTemplate="{StaticResource TimestampMessage}"
ImageMessageTemplate="{StaticResource ImageMessage}"
x:Key="messageTypeDataTemplateSelector" />
<DataTemplate x:Key="TextMessage">
<Grid Grid.ColumnSpan="3" RowSpan="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width=".5*"/>
<ColumnDefinition Width="70*"/>
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding UserName}" Visibility="{Binding Source={StaticResource chatSettings}, Path=HideAvatars, Converter={StaticResource booleanToVisibility}}" FontWeight="Bold" TextAlignment="Right" Grid.Column="0" Width="150" />
<Image VerticalAlignment="Top" Source="{Binding AvatarUrl}" Visibility="{Binding Source={StaticResource chatSettings}, Path=ShowAvatars, Converter={StaticResource booleanToVisibility}}" Grid.Column="0" Width="60" Margin="0,0,10,0" />
<TextBlock Text=" : " Visibility="{Binding Source={StaticResource chatSettings}, Path=HideAvatars, Converter={StaticResource booleanToVisibility}}" Grid.Column="1" />
<RichTextBlock Loaded="FrameworkElement_OnLoaded" TextWrapping="Wrap" Grid.Column="2" />
</Grid>
</DataTemplate>
答案 0 :(得分:4)
你是完全正确的。 WinRT中没有OnDataBinding事件。这个想法怎么样:
为RichTextBlock(http://msdn.microsoft.com/en-us/library/ms749011(v=vs.110).aspx)创建一个AttachedProperty,然后将您的项目绑定到该项目。当您注册Attached Property时,在FrameworkPropertyMetadata中,您可以指定一个PropertyChangedCallback,只要Attached Property的值发生更改,它就会触发。像这样:
目前,要确保它正常工作,请在当前的.xaml.cs文件中执行以下操作:
public static readonly DependencyProperty RichTextBlockItemProperty = DependencyProperty.RegisterAttached(
"RichTextBlockItem",
typeof(object),
typeof(RichTextBlock),
new PropertyMetadata(null, RichTextBlockItemChanged)
);
// Don't forget this!
public static object GetRichTextBlockItem(DependencyObject obj)
{
return (object)obj.GetValue(RichTextBlockItemProperty);
}
// And this!
public static void SetRichTextBlockItem(DependencyObject obj, object value)
{
obj.SetValue(RichTextBlockItemProperty, value);
}
public void RichTextBlockItemChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
// Here you can do whatever you wish. This method will fire when the item is bound.
// d is the RichTextBlock object.
// e.NewValue is the value that was just bound.
// So, from here you can dynamically add your Runs/Images/etc
}
然后在.xaml文件中确保添加本地命名空间,以便执行此操作:
<Page .... xmlns:local="using:CurrentXamlPageNamespace".../>
<DataTemplate x:Key="TextMessage">
<Grid Grid.ColumnSpan="3" RowSpan="1">
<!-- I got rid of the other xaml just to hightlight my answer. But you still need it. -->
<RichTextBlock local:RichTextBlock.RichTextBlockItem="{Binding}" TextWrapping="Wrap" Grid.Column="2" />
</Grid>
</DataTemplate>