Использование TextWrap в пользовательском элементе управления - PullRequest
0 голосов
/ 24 сентября 2019

Я создал пользовательский элемент управления, который отображает строку (Var1) разных цветов в соответствии с файлом ColorCode1:

<local:MyFormattedTextControl Text="{Binding SelectedItem.Var1, ElementName=myListView, UpdateSourceTrigger=PropertyChanged}" PartFlags="{Binding SelectedItem.ColorCode1, ElementName=myListView}"  />

Это работает отлично, за исключением одной детали: я не могу использовать TextWrapping = "Wrap" Может кто-нибудь сказать мне, как обновить пользовательский элемент управления, чтобы иметь возможность использовать TextWrappin?

Пользовательский элемент управления выглядит следующим образом:

<UserControl 
    <UserControl.Resources>
        <local:PartColorValueConverter x:Key="partColorValueConv" />
    </UserControl.Resources>
    <Grid>
        <StackPanel x:Name="myStackPanel" Orientation="Horizontal"/>
    </Grid>
</UserControl>

Код позади дляэтот пользовательский элемент управления:

public partial class MyFormattedTextControl : UserControl, INotifyPropertyChanged {

//Constructor
public MyFormattedTextControl() {
    InitializeComponent();
    myStackPanel.DataContext = this;
}

//Creating Dependency Properties for Text and ColorCode
public string Text {
    get { return (string)GetValue(TextProperty); }
    set { SetValue(TextProperty, value); }
}
public IEnumerable<int> PartFlags {
    get { return (int[])GetValue(PartFlagsProperty); }
    set { SetValue(PartFlagsProperty, value); }
}
public static readonly DependencyProperty TextProperty = DependencyProperty.Register("Text", typeof(string), typeof(MyFormattedTextControl), new PropertyMetadata(null, OnTextPropertyChanged));
public static readonly DependencyProperty PartFlagsProperty = DependencyProperty.Register("PartFlags", typeof(int[]), typeof(MyFormattedTextControl), new PropertyMetadata(new int[] { }));

//OnPropertyChange
private static void OnTextPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) {

    //Get Object
    var ctrl = (MyFormattedTextControl)d;
    var t = (string)e.NewValue;
    ctrl.myStackPanel.Children.Clear();

    //Fill Array with single characters
    for (int i = 0; i < t.Length; i++) {

        //Create TextBox
        TextBlock tb = new TextBlock();
        tb.Text = t.Substring(i, 1);

        Binding b = new Binding("PartFlags");
        PartColorValueConverter conv = new PartColorValueConverter();
        b.Converter = conv;
        b.ConverterParameter = i;
        tb.SetBinding(ForegroundProperty, b);

        //Add Text Box to StackPanel
        ctrl.myStackPanel.Children.Add(tb);
    }
}

private void OnPropertyChanged([CallerMemberName] string callerMember = "") {
    PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(callerMember));
}
public event PropertyChangedEventHandler PropertyChanged;

}

1 Ответ

0 голосов
/ 24 сентября 2019

Ваша проблема в том, что вы используете много текстовых блоков вместо одного.

Текстовый блок содержит строчные.Это могут быть разные вещи, например, перевод строки.Наиболее распространенным является бег.

Следовательно, вы можете сделать:

<TextBlock TextWrapping="Wrap">
        <Run Foreground="Red">A</Run>
        <Run Foreground="Blue">b</Run>
        <Run Foreground="Green">c</Run>
</TextBlock>

Очистить строки и добавить прогон для каждой буквы с соответствующим текстом и передним планом.

https://docs.microsoft.com/en-us/dotnet/api/system.windows.controls.textblock.inlines?view=netframework-4.8

...