How to collapse a paragraph?
How can I make a Paragra开发者_开发百科ph collapsible in a FlowDocument while keeping its text selectable?
This has to be one of the ugliest extensions ever (in terms of code and visuals) but it "makes a Paragraph collabsible" and the text is still selectable.
public static class ParagraphExtensions
{
private static Dictionary<Paragraph, InlineUIContainer> _collapseButtonDictionary;
private static Dictionary<Paragraph, List<Inline>> _paragraphInlineStorage;
public static readonly DependencyProperty IsCollapsibleProperty =
DependencyProperty.RegisterAttached("IsCollapsible", typeof(bool), typeof(Paragraph), new UIPropertyMetadata(false, IsCollapsibleChanged));
public static bool GetIsCollapsible(DependencyObject obj)
{
return (bool)obj.GetValue(IsCollapsibleProperty);
}
public static void SetIsCollapsible(DependencyObject obj, bool value)
{
obj.SetValue(IsCollapsibleProperty, value);
}
private static void IsCollapsibleChanged(object sender, DependencyPropertyChangedEventArgs e)
{
if (_collapseButtonDictionary == null) _collapseButtonDictionary = new Dictionary<Paragraph, InlineUIContainer>();
if (_paragraphInlineStorage == null) _paragraphInlineStorage = new Dictionary<Paragraph, List<Inline>>();
Paragraph p = sender as Paragraph;
if ((bool)e.NewValue)
{
InlineUIContainer container;
if (_collapseButtonDictionary.ContainsKey(p))
{
container = _collapseButtonDictionary[p];
}
else
{
ToggleButton button = new ToggleButton() { Tag = p, Content = "Hide" };
container = new InlineUIContainer() { Child = button };
_collapseButtonDictionary.Add(p, container);
button.Click += new RoutedEventHandler(CollapseButton_Click);
}
if (p.Inlines.Count > 0)
{
p.Inlines.InsertBefore(p.Inlines.First(), container);
}
else
{
p.Inlines.Add(container);
}
}
else
{
if (_collapseButtonDictionary.ContainsKey(p))
{
var container = _collapseButtonDictionary[p];
var tb = container.Child as ToggleButton;
if ((bool)tb.IsChecked) SetCollapsedState(false, p);
p.Inlines.Remove(container);
_collapseButtonDictionary.Remove(p);
}
}
}
private static void CollapseButton_Click(object sender, RoutedEventArgs e)
{
ToggleButton button = sender as ToggleButton;
var p = button.Tag as Paragraph;
SetCollapsedState((bool)button.IsChecked, p);
}
private static void SetCollapsedState(bool isCollapsed, Paragraph p)
{
InlineUIContainer buttonContainer = _collapseButtonDictionary[p];
List<Inline> disabledInlines;
if (_paragraphInlineStorage.ContainsKey(p))
{
disabledInlines = _paragraphInlineStorage[p];
}
else
{
disabledInlines = new List<Inline>();
_paragraphInlineStorage.Add(p, disabledInlines);
}
if (isCollapsed)
{
foreach (var item in p.Inlines)
{
disabledInlines.Add(item);
}
p.Inlines.Clear();
p.Inlines.Add(buttonContainer);
}
else
{
p.Inlines.Clear();
foreach (var item in disabledInlines)
{
p.Inlines.Add(item);
}
disabledInlines.Clear();
}
}
}
<Paragraph local:ParagraphExtensions.IsCollapsible="True">Lorem Ipsum</Paragraph>
Litterally making the paragraph collapsible is probably not the best approach, i think this kind of functionality is rather something the panel/enveloping document should take care of.
精彩评论