.net 如何折叠段落?
如何在保持文本可选性的同时使段落在FlowDocument中可折叠?这必须是有史以来最丑陋的扩展之一(在代码和视觉方面),但它“使段落可协作”,并且文本仍然是可选的.net 如何折叠段落?,.net,wpf,flowdocument,paragraph,.net,Wpf,Flowdocument,Paragraph,如何在保持文本可选性的同时使段落在FlowDocument中可折叠?这必须是有史以来最丑陋的扩展之一(在代码和视觉方面),但它“使段落可协作”,并且文本仍然是可选的 public static class ParagraphExtensions { private static Dictionary<Paragraph, InlineUIContainer> _collapseButtonDictionary; private static Dictionary<
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();
}
}
}
公共静态类段落扩展
{
私有静态字典(collapseButtonDictionary);;
专用静态字典_段线性存储;
公共静态只读从属属性IsCollappibleProperty=
DependencyProperty.RegisterAttached(“IsCollapsible”、typeof(bool)、typeof(段落)、新UIPropertyMetadata(false、IsCollapsibleChanged));
公共静态bool GetIsCollapsible(DependencyObject obj)
{
返回(bool)对象GetValue(IsCollapsibleProperty);
}
公共静态void SetIsCollapsible(DependencyObject对象,布尔值)
{
对象设置值(IsCollapsibleProperty,value);
}
私有静态void IsCollapsibleChanged(对象发送方,DependencyPropertyChangedEventArgs e)
{
如果(_collapseButtonDictionary==null)_collapseButtonDictionary=newdictionary();
如果(_paragraphInlineStorage==null)_paragraphInlineStorage=new Dictionary();
第p段=发送方作为第3段;
if((bool)e.NewValue)
{
内联集装箱;
if(_collapseButtonDictionary.ContainsKey(p))
{
容器=_collapseButtonDictionary[p];
}
其他的
{
ToggleButton=newtogglebutton(){Tag=p,Content=“Hide”};
container=newinlineuicontainer(){Child=button};
_collapseButtonDictionary.Add(p,容器);
按钮。单击+=新建路由EventHandler(折叠按钮单击);
}
如果(p.Inlines.Count>0)
{
p、 InsertBefore(p.Inlines.First(),容器);
}
其他的
{
p、 Inlines.Add(容器);
}
}
其他的
{
if(_collapseButtonDictionary.ContainsKey(p))
{
var容器=_collapseButtonDictionary[p];
var tb=container.Child作为ToggleButton;
如果((bool)tb.IsChecked)设置CollapsedState(false,p);
p、 内联线。移除(容器);
_折叠式按钮缩略。移除(p);
}
}
}
专用静态空白折叠按钮单击(对象发送器,路由目标e)
{
ToggleButton=发送方为ToggleButton;
var p=按钮。标记为段落;
SetCollapsedState((bool)button.IsChecked,p);
}
私有静态void SetCollapsedState(bool isCollapsed,第p段)
{
InlineUIContainer buttonContainer=_collapseButtonDictionary[p];
列出不可禁用的数据线;
如果(_段落linestorage.ContainsKey(p))
{
DisabledLines=_段落线性存储[p];
}
其他的
{
disabledInlines=新列表();
_段落linestorage.Add(p,disabledInlines);
}
如果(已合并)
{
foreach(p.Inlines中的变量项)
{
禁用dinlines。添加(项);
}
p、 Inlines.Clear();
p、 添加(按钮容器);
}
其他的
{
p、 Inlines.Clear();
foreach(不允许的行中的var项)
{
p、 内联线。添加(项目);
}
禁用dinlines.Clear();
}
}
}
Lorem Ipsum
随意将段落折叠可能不是最好的方法,我认为这种功能应该由面板/信封文档来处理。我想知道这是否仍然与您相关,但要回答这个问题,我必须问:如何选择要折叠的段落中的文本?(重新措辞:折叠段落=>无文本=>选择什么?)
<Paragraph local:ParagraphExtensions.IsCollapsible="True">Lorem Ipsum</Paragraph>