[英]WPF TextBlock with custom StringFormat and variable number of Run/Inline
我有一個需要顯示的短語列表。 這些短語具有靜態文本和可變數量的位,需要在屏幕上突出顯示(粗體,顏色不同)。
如果我要從xaml構建所有內容,這是一個示例。
<TextBlock Grid.Row="2">
<Run Text="Your"/>
<Run Text="{Binding Text1}"/>
<Run Text="has a limit of $"/>
<Run Text="{Binding Limit}" FontWeight="Bold" Foreground="Red"/>
<Run Text="for period "/>
<Run Text="{Binding StartDate}" FontWeight="Bold" Foreground="Blue"/>
<Run Text=" : "/>
<Run Text="{Binding EndDate}" FontWeight="Bold" Foreground="Blue"/>
<Run Text=". Your up to date expenses are $"/>
<Run Text="{Binding Expenses}" FontWeight="Bold" Foreground="Red"/>
</TextBlock>
<TextBlock Grid.Row="3">
<Run Text="Your"/>
<Run Text="{Binding Text2}"/>
<Run Text="has a limit of $"/>
<Run Text="{Binding Limit2}" FontWeight="Bold" Foreground="Red"/>
<Run Text="for period "/>
</TextBlock>
我想要實現的是以某種方式將文本與{0}綁定在一起,並綁定ItemsSource
,它將為TextBlock
設置Inlines
,並且進一步為每個內聯樣式(字體粗細和文本顏色)綁定ItemsSource
應該有:
文字:您的{0}的期間上限為$ {1}。
填充內聯的值:abc,1000
適用的樣式{none,none},{bold,red}
首先有可能嗎? 如果是這樣,您能為我指出正確的方向還是給我一些提示?
謝謝。
我將為此創建一個自定義TextBlock
后代,並以編程方式創建內聯。
首先,創建一個模型來控制文本的顯示:
public class TextModel
{
public string Text { get; set; }
public Color Color { get; set; }
public FontWeight Weight { get; set; }
}
您可能要對此實現INotifyPropertyChanged
,盡管稍后會使事情復雜化。
接下來,您需要以下這些的集合:
public class TextModelCollection : ObservableCollection<TextModel>
{
}
最后,創建一個派生自TextBlock
的自定義類:
public class MyCustomTextBlock : TextBlock
{
public static readonly DependencyProperty ItemsProperty =
DependencyProperty.Register("Items", typeof(TextModelCollection),
typeof(MyCustomTextBlock), new PropertyMetadata(OnItemsChanged));
public TextModelCollection Items
{
get
{
return (TextModelCollection) GetValue(ItemsProperty);
}
set
{
SetValue(ItemsProperty, value);
}
}
public MyCustomTextBlock()
{
RefreshInlines();
}
static void OnItemsChanged(DependencyObject d,
DependencyPropertyChangedEventArgs e)
{
((MyCustomTextBlock) d).RefreshInlines();
}
}
然后,您只需要一個方法(在此稱為RefreshInlines
),即可在自定義屬性更改時刷新文本塊的inlines集合。
void RefreshInlines()
{
Inlines.Clear();
foreach (TextModel text in Items)
{
var run = new Run(text.Text);
run.Foreground = new SolidColorBrush(text.Color);
run.FontWeight = text.Weight;
Inlines.Add(run);
}
}
由於TextModelCollection
是可觀察的集合,因此您需要注冊列表更改,以便在添加或刪除項目時刷新內聯。 我沒有在這里顯示該代碼,但它基本上與OnItemsChanged
方法相關。
這實際上是兩個問題:
您正在尋找MultiBinding
和StringFormat
:
這是針對文本以靜態文本開頭的情況:
<TextBlock>
<TextBlock.Text>
<MultiBinding StringFormat="Write Static Text Here {1} Something else {1}">
<Binding Path="Text2" />
<Binding Path="Text2" />
</MultiBinding>
</TextBlock.Text>
</TextBlock>
這是針對Text以可變文本開頭的情況:
<TextBlock>
<TextBlock.Text>
<MultiBinding StringFormat="{}{0} Write Static Text Here {1} Something else">
<Binding Path="Text2" />
<Binding Path="Text2" />
</MultiBinding>
</TextBlock.Text>
</TextBlock>
您需要使用諸如ItemsControl
東西( ListBox
DataGrid
等)
<ItemsControl ItemsSource="{Binding MyList}">
<ItemsControl.ItemTemplate>
<DataTemplate>
put anything here to display as an element of MyList
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
您還需要在窗口的DataContext
中為MyList
創建一個集合。 例如:
public MainWindow()
{
InitializeComponent();
var vm = new MainVm();
DataContext = vm;
}
這個MainVm
應該從DependencyObject
派生,並包含類似以下內容:
public ObservableCollection<string> MyList { get { return _myList; } }
private ObservableCollection<string> _myList = new ObservableCollection<string>();
有關更多信息,請訪問google MVVM。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.