[英]WPF - Display TextBlock with different colors
因此,我們要做的是顯示一個TextBlock,每行使用不同的顏色,理想情況下,我想使用綁定。
我的TextBlock可能顯示項目列表,每個項目都有Texte和Color屬性。 對於foreach,我想使用Texte屬性以指定的顏色顯示每個項目一行。
我已經嘗試了以下方法:
1)我制作了一個TextBlock,其Text綁定到ViewModel中的字符串屬性,並且使用foreach我只是填充字符串,但是在那種情況下,不能按我希望的那樣在每行上應用顏色。
2)我發現堆棧上的鏈接有所幫助,建議在其中使用Run
。
所以在我的ViewModel中,我像這樣填充TextBlock:
private TextBlock legende;
public TextBlock Legende
{
get { return legende; }
set
{
legende = value;
this.NotifyPropertyChanged("Legende");
}
}
public void UpdateLegend(Legend legende)
{
this.Legende = new TextBlock();
this.Legende.TextWrapping = TextWrapping.Wrap;
this.Legende.Margin = new Thickness(10);
this.Legende.FontSize = 14;
this.Legende.LineStackingStrategy=LineStackingStrategy.BlockLineHeight;
this.Legende.LineHeight = 20;
int i = 0;
foreach(LegendItem item in legende.list)
{
if(i==0)
{
Run run = new Run(item.Texte);
run.Foreground = item.Color;
this.Legende.Inlines.Add(run);
}
else
{
Run run = new Run(")\r\n"+item.Texte);
run.Foreground = item.Color;
this.Legende.Inlines.Add(run);
}
i++;
}
}
每當我需要更新圖例時,我的模型都會執行以下操作:
contexte.UpdateLegend(MonGraphe.Legende);
this.CanvasLegend = contexte.Legende;
然后我的看法:
<Grid Grid.Column="2" Background="WhiteSmoke">
<TextBlock x:Name="CanvasLegend" TextAlignment="Left" HorizontalAlignment="Left"/>
</Grid>
現在它根本不起作用,我找不到原因。 我也想在ViewModel中做所有事情,但是為此,我需要將Textlock綁定到ViewModel中定義的TextBlock,但是找不到該怎么做?
編輯:
如Icebat所述,我正在使用以下轉換器:
XML與IceBat相同
ViewModel:
public class ColoringConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
//is your collection IEnumerable<>? If not, adjust as needed
var legende = value as Legend;
if (legende == null) return value;
return legende.list.Select(i => new Run() { Text = i.Texte, Foreground = i.Color }).ToArray();
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
class ViewModelMainWindow : INotifyPropertyChanged
{
private Legend legende;
public Legend Legende
{
get { return legende; }
set
{
legende = value;
this.NotifyPropertyChanged("Legende");
}
}
}
還包括我的“傳奇”課程,因為我認為這是一個令人誤解的地方:
public class LegendItem
{
public int Type { get; set; }
public double Diametre { get; set; }
public double Longueur { get; set; }
public double Profondeur { get; set; }
public string Texte { get; set; }
public Brush Color { get; set; }
public LegendItem()
{
}
}
public class Legend : INotifyPropertyChanged
{
private ObservableCollection<LegendItem> liste;
public ObservableCollection<LegendItem> Liste
{
get { return liste; }
set
{
liste=value;
NotifyPropertyChanged(ref liste, value);
}
}
public Legend()
{
this.list = new ObservableCollection<LegendItem>();
}
public event PropertyChangedEventHandler PropertyChanged;
public void NotifyPropertyChanged(string propName)
{
if (this.PropertyChanged != null)
this.PropertyChanged(this, new PropertyChangedEventArgs(propName));
}
private bool NotifyPropertyChanged<T>(ref T variable, T valeur, [CallerMemberName] string nomPropriete = null)
{
if (object.Equals(variable, valeur)) return false;
variable = valeur;
NotifyPropertyChanged(nomPropriete);
return true;
}
public Legend(Repere rep)
{
List < Brush > listColors = new List<Brush>();
listColors.Add(Brushes.Red);
listColors.Add(Brushes.MediumBlue);
listColors.Add(Brushes.Purple);
listColors.Add(Brushes.LimeGreen);
listColors.Add(Brushes.DarkOrange);
listColors.Add(Brushes.Navy);
listColors.Add(Brushes.DarkRed);
listColors.Add(Brushes.Chartreuse);
listColors.Add(Brushes.DodgerBlue);
listColors.Add(Brushes.Tomato);
this.list = new ObservableCollection<LegendItem>();
List<Percage> listPer = rep.liste_percages;
List<GroupePercage> listeGp = rep.listeGpPercages;
foreach (Percage per in listPer)
{
LegendItem itemExists = this.list.FirstOrDefault(x => x.Type == per.Type && x.Diametre == per.Diametre && x.Profondeur == per.Depth&&x.Longueur==per.Longueur);
if (itemExists == null)
{
LegendItem newItem = new LegendItem();
newItem.Type = per.Type;
switch (newItem.Type)
{
case 51: newItem.Texte = "DRILL "; break;
case 58: newItem.Texte = "CounterSink "; break;
case 59: newItem.Texte = "Tapping "; break;
case 12: newItem.Texte = "Slot "; break;
default: newItem.Texte = "NOT FOUND "; break;
}
newItem.Diametre = per.Diametre;
newItem.Longueur = per.Longueur;
newItem.Texte += newItem.Diametre.ToString();
if (newItem.Type==12)
{
newItem.Texte = newItem.Diametre + " x " + newItem.Longueur;
}
newItem.Profondeur = per.Depth;
this.list.Add(newItem);
}
}
foreach (GroupePercage per in listeGp)
{
LegendItem itemExists = this.list.FirstOrDefault(x => x.Type == per.Type && x.Diametre == per.Diametre && x.Profondeur == per.Depth && x.Longueur == per.Longueur);
if (itemExists == null)
{
LegendItem newItem = new LegendItem();
newItem.Type = per.Type;
switch (newItem.Type)
{
case 51: newItem.Texte = "DRILL "; break;
case 58: newItem.Texte = "CounterSink "; break;
case 59: newItem.Texte = "Tapping "; break;
case 12: newItem.Texte = "Slot "; break;
default: newItem.Texte = "NOT FOUND "; break;
}
newItem.Diametre = per.Diametre;
newItem.Longueur = per.Longueur;
newItem.Texte += newItem.Diametre.ToString();
if (newItem.Type == 12)
{
newItem.Texte = newItem.Diametre + "x" + newItem.Longueur;
}
newItem.Profondeur = per.Depth;
this.list.Add(newItem);
}
}
for(int i=0;i<this.list.Count();i++)
{
this.list[i].Color = listColors[Math.Min(i,9)];
}
}
}
好吧,Runs的方法似乎是最簡單的方法。 不知道哪里出了問題,但這應該相對容易。 您可以僅將ItemsControl
用於內聯:
<TextBlock x:Name="CanvasLegend" TextAlignment="Left" HorizontalAlignment="Left">
<TextBlock.Inlines>
<ItemsControl ItemsSource="{Binding LegendItems, ElementName=me,
Converter={StaticResource coloringConverter}}" />
</TextBlock.Inlines>
</TextBlock>
為了簡單起見,我使用ElementName
指向宿主窗口,但是您可以將其綁定到ViewModel。 轉換器看起來像這樣:
public class ColoringConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
//is your collection IEnumerable<>? If not, adjust as needed
var legend = value as IEnumerable<LegendItem>;
if (legend == null) return value;
return legend.Select(i => new Run() { Text = i.Text, Foreground = i.Color }).ToArray();
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
然后只需將轉換器添加到資源中的某個位置(在我的示例中是Window):
<Window.Resources>
<local:ColoringConverter x:Key="coloringConverter" />
</Window.Resources>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.