gpt4 book ai didi

c# - 如果在 WinRT 中设置为绑定(bind),则不会设置自定义模板控件的依赖属性

转载 作者:行者123 更新时间:2023-11-30 21:52:10 36 4
gpt4 key购买 nike

我编写了一个自定义模板化 RichTextBlock,以便将表情符号和链接分别表示为图像和超链接按钮。它基本上只有一个“文本”依赖属性,因为当它收到纯文本/字符串时,所有转换工作都将在控件内部处理。

问题是如果 Text 属性带有一些特定的字符串,如 Text="asdasdsa",控件将正确表示“asdasdas”。如果该属性设置为绑定(bind)类似 Text="{Binding something}"的内容,则该控件将不起作用,并且 setter Text 依赖属性将永远不会触发。

控件的样式基本是这样

<Style TargetType="local:MyRichTextBlock" >
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local:MyRichTextBlock">
<Border HorizontalAlignment="Center" Width="auto" Height="auto">
<StackPanel>
<RichTextBlock x:Name="ChildRichTextBlock"/>
</StackPanel>
</Border>

</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

基本上,它将纯文本转换并替换 XAML 中的那些表情符号和超链接,最后将 XAML 代码块作为段落添加到 RichTextBlock 中。

控件代码

public sealed class MyRichTextBlock : Control
{
RichTextBlock _richTextBlock;
StringBuilder builder = new StringBuilder();
Regex urlRx = new Regex(@"(?<url>(http:[/][/]|www.)([a-z]|[A-Z]|[0-9]|[/.]|[~])*)", RegexOptions.IgnoreCase);


public MyRichTextBlock()
{
this.DefaultStyleKey = typeof(MyRichTextBlock);

foreach (var key in emojiDict.Keys)
{
builder.Append(key.Replace("[", @"\[").Replace("]", @"\]"));
builder.Append("|");
}
builder.Remove(builder.Length - 1, 1);
}



private readonly Dictionary<string, string> emojiDict = new Dictionary<string, string>
{
//Dictionary of emojis key
};

protected override void OnApplyTemplate()
{
_richTextBlock = GetTemplateChild("ChildRichTextBlock") as RichTextBlock;
SetRichTextBlock(Text);
}


public String Text
{
get { return (String)GetValue(TextProperty); }
set { SetValue(TextProperty, value); } //This setter won't fire
}

// Using a DependencyProperty as the backing store for Text. This enables animation, styling, binding, etc...
public static readonly DependencyProperty TextProperty =
DependencyProperty.Register("Text", typeof(String), typeof(MyRichTextBlock), new PropertyMetadata(""));



//Conversion work, it does not really related to the property I think
private void SetRichTextBlock(string value)
{
string abc = value;
MatchCollection matches = urlRx.Matches(value);
var r = new Regex(builder.ToString());
var mc = r.Matches(value);
foreach (Match m in mc)
{
value = value.Replace(m.Value, string.Format(@"<InlineUIContainer><Border><Image Source=""ms-appx:///Assets/Emoji/{0}.png"" Margin=""2,0,2,0"" Width=""30"" Height=""30""/></Border></InlineUIContainer>", emojiDict[m.Value]));
}
foreach (Match match in matches)
{
string url = match.Groups["url"].Value;
value = value.Replace(url,
string.Format("<InlineUIContainer><Border><HyperlinkButton Margin=\"0,0,0,-4\" Padding=\"0,2,0,0\" NavigateUri =\"{0}\"><StackPanel HorizontalAlignment=\"Center\" Height=\"25\" Width=\"90\" Background=\"#FFB8E9FF\" Orientation = \"Horizontal\"><Image Margin=\"5,0,0,0\" Source = \"/Assets/Link.png\" Width = \"15\" Height = \"15\"/><TextBlock Margin=\"4,2.5,0,0\" Text=\"网页链接\" Foreground=\"White\" FontFamily=\"Microsoft YaHei UI\" FontSize=\"14\" FontWeight=\"Bold\"/></StackPanel ></HyperlinkButton></Border></InlineUIContainer>", url));
}
value = value.Replace("\r\n", "<LineBreak/>");


var xaml = string.Format(@"<Paragraph
xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation""
xmlns:x=""http://schemas.microsoft.com/winfx/2006/xaml"">
<Paragraph.Inlines>
<Run></Run>
{0}
</Paragraph.Inlines>
</Paragraph>", value);
var p = (Paragraph)XamlReader.Load(xaml);
_richTextBlock.Blocks.Add(p);
}
}

以及我如何使用这个控件的方式

<DataTemplate x:Name="NormalTemplate">
<Grid Grid.Column="1"
Grid.Row="1"
d:LayoutOverrides="LeftMargin, RightMargin, TopMargin, BottomMargin"
Margin="0,15,0,15"
Name="NormalTemplateGrid">

//Codes omit//

<local:MyRichTextBlock x:Name="WeiboTextTextblock"
Margin="20,35,0,0"
Text="{Binding Text}"
Grid.Column="2"
Grid.Row="1"
d:LayoutOverrides="HorizontalAlignment, TopMargin, BottomMargin, LeftPosition, RightPosition, TopPosition, BottomPosition"
HorizontalAlignment="Left"
FontFamily="Microsoft YaHei"/>
</Grid>
</DataTemplate>

任何想法是什么问题以及解决方案是什么?

最佳答案

setter 只是为了完成一个依赖属性。您需要为 Text 属性定义一个属性更改回调,如下所示 -

public static readonly DependencyProperty TextProperty =
DependencyProperty.Register(nameof(Text), typeof(String), typeof(MyRichTextBlock), new PropertyMetadata("", OnTextChange));

private static void OnTextChange(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var rtb = (MyRichTextBlock)d;
rtb.SetRichTextBlock(e.NewValue.ToString());
}

关于c# - 如果在 WinRT 中设置为绑定(bind),则不会设置自定义模板控件的依赖属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35031511/

36 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com