我创建了一个新的TextBlock类,它具有ItemsSource属性并将ItemsSource转换为“Run”对象:
public class MultiTypeDynamicTextBlock : TextBlock
{
public interface ISection
{
Inline GetDisplayElement();
}
public class TextOption : ISection
{
private Run mText;
public TextOption(string aText)
{
mText = new Run();
mText.Text = aText.Replace("\\n", "\n");
}
public Inline GetDisplayElement()
{
return mText;
}
}
public class LineBreakOption : ISection
{
public Inline GetDisplayElement()
{
return new LineBreak();
}
public ISection Clone()
{
return new LineBreakOption();
}
}
public class ImageOption : ISection
{
private InlineUIContainer mContainer;
public ImageOption(string aDisplay)
{
Image lImage;
lImage = new Image();
lImage.Source = new BitmapImage(new Uri(Environment.CurrentDirectory + aDisplay));
lImage.Height = 15;
lImage.Width = 15;
mContainer = new InlineUIContainer(lImage);
}
public Inline GetDisplayElement()
{
return mContainer;
}
}
public static readonly DependencyProperty ItemsSourceProperty =
DependencyProperty.Register("ItemsSource", typeof(ObservableCollection<ISection>), typeof(MultiTypeDynamicTextBlock),
new UIPropertyMetadata(new ObservableCollection<ISection>(),
new PropertyChangedCallback(SetContent)));
public ObservableCollection<ISection> ItemsSource
{
get
{
return GetValue(ItemsSourceProperty) as ObservableCollection<ISection>;
}
set
{
if (ItemsSource != null)
ItemsSource.CollectionChanged -= CollectionChanged;
SetValue(ItemsSourceProperty, value);
SetContent();
ItemsSource.CollectionChanged += CollectionChanged;
}
}
private void CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
SetContent();
}
private static void SetContent(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
DependencyObject lParent = d;
MultiTypeDynamicTextBlock lPanel = lParent as MultiTypeDynamicTextBlock;
if (lPanel != null)
{
lPanel.ItemsSource = e.NewValue as ObservableCollection<ISection>;
}
}
private void SetContent()
{
if (ItemsSource != null)
{
Inlines.Clear();
foreach (ISection lCurr in ItemsSource)
{
Inlines.Add(lCurr.GetDisplayElement());
}
}
}
如果我将ItemsSource直接绑定到DataContext,它可以工作 . 但是如果我将它绑定到在运行时更改的对象(例如ListBox上的SelectedItem),则在选择新项时它不会更新文本 .
<StackPanel>
<ListBox x:Name="TheList" ItemsSource="{Binding Items}" SelectedItem="{Binding SelectedItem}">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Title}"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<StackPanel DataContext="{Binding ElementName=TheList, Path=SelectedItem}">
<TextBlock Text="{Binding Title}" FontSize="20"/>
<local:MultiTypeDynamicTextBlock ItemsSource="{Binding Items}"/>
</StackPanel>
</StackPanel>
有什么理由吗?
2 回答
在您的示例中,
SelectedItem
是否有两个属性Title
和Items
?或者Items
是您的viewmodel中的属性?如果答案是后者,那么你可以在下面找到解决方案 .我不试试看 . 如果您的意思是未设置自定义控件上的
ItemsSource
,则必须将XAML
指向正确的方向 . 如果这是您想要实现的目标,您可以在下面找到解决方案 . 我所做的是用这行代码将编译器指向正确的源代码:在这里,您说编译器可以在窗口的
DataContext
(或任何可以找到property
的控件)中找到Binding property
.希望这有帮助 .
EDIT
当我从
ListBox
中选择另一个时,title property
会发生变化 . 如果Items
设置为新的ObservableCollection
,当SelectedItem
更改时,是否为Items
调用OnPropertyChanged event
?谢谢您的帮助 . 我设法通过更新MultiTypeDynamicTextBlock来解决这个问题,如下所示:
并且我将Binded的字段更新为MultiTypeDynamicTextBlock.SectionList类型
只要我使用副本(克隆)它正在工作,由于某种原因,当我不克隆它从列表中的显示删除值,如果有人知道为什么我会喜欢学习但我设法绕过它 . 窗口的XAML是: