-1

I have a wpf app, c# that displays texts (teahcer's name) when a combobox is closed. Basically it is contained in 1 string and being passed to the classInstance.TeachersComboBoxText or Text="{Binding Path=TeachersComboBoxText}" . Everything is great but the client is requesting for the text to be in italic if the teacher is flagged as not default or secondary teacher. Basically, I need to have a string but different font styles is applied to it,depends on my data.

<ComboBox Name="instanceTeachersComboBox"
        IsEditable="True"
        IsReadOnly="True"
        ItemsSource="{Binding Path=TeacherList}" DropDownClosed="teachersComboBox_DropDownClosed"
        Text="{Binding Path=TeachersComboBoxText}"
        FontWeight="{Binding Path=IsSelectedFontWeight}">
    <ComboBox.ItemTemplate>
        <DataTemplate>
            <StackPanel Orientation="Horizontal">
                <CheckBox IsChecked="{Binding Path=IsSelected}" 
                        Background="{Binding Path=IsActiveColour}"
                        Content="{Binding Path=Display}" 
                        Foreground="{Binding Path=IsClashColour}" 
                        FontStyle="{Binding Path=EndDateFontStyle}"/>
                <Image Source="/SchoolEdgeTimetable;component/Images/greentick16x16.png" 
                       Margin="5,0,0,0" 
                       Visibility="{Binding Path=IsSpecialitySubjectVisibility}"></Image>
            </StackPanel>
        </DataTemplate>
    </ComboBox.ItemTemplate>
</ComboBox>

=== this is the code ====

if (classInstance.TeacherList.Any(c => c.IsSelected == true && c.IsDefault == false) || instanceCount != defaultCount)
{
    System.Windows.Forms.RichTextBox rtf = new System.Windows.Forms.RichTextBox();
    foreach (var item in data)
    {
        if (!item.IsDefault)
        {
            rtf.SelectionFont = new Font("Arial", 12, System.Drawing.FontStyle.Italic);
            rtf.AppendText(item.Display);
        }          
        text = GT.Join2Strings(text, item.IsDefault? item.Display : rtf.Text, "\n");
    }
}
else
    text = DEFAULT_TEXT;
classInstance.TeachersComboBoxText = text;

I tried rtf because it seems that I can't apply it in plain string, but the code is not working. Is there any way to solve this without using rtf? or if not why is my code not working? anyone ca suggest a better way to do this will be appreciated. thanks

UPDATE: People are suggesting to modify the template which I already did, that is working great in showing the items when a combobox is open. One of my items is RED and in italic as you can see BUT What I am trying to do though is modify display of the combobox TEXT property. I have attached an image to get a better view on what I mean. thanks enter image description here

mm8
  • 163,881
  • 10
  • 57
  • 88
user742102
  • 1,335
  • 8
  • 32
  • 51

3 Answers3

0

It's pretty simple if you know how to utilise <Run> tag of TextBlock control in code behind. See below code:

//loop through all the teachers
foreach (var teacher in vm.Teachers)
{
    //check if teacher is default
    if (teacher.IsDefault)
        {   
            //add text to "tb" textblock, in italic style
            tb.Inlines.Add(new Run(teacher.Name) { FontStyle = FontStyles.Italic });
        }
    else
        {
            //add text to "tb" textblock
            tb.Inlines.Add(new Run(teacher.Name));
        }
}

If you are keen to know more about inline formatting, here is a cool blog post for same. Let me know if you need any more help on this.

Naresh Ravlani
  • 1,600
  • 13
  • 28
  • Hi, I saw something about inline already but I am not sure I can use it inside a combobox? If you can see I am binding the string(selected teacher - teacher's name) to the Text property of a combobox and not a textblock. I would have added a template that has a textlock but how? How can I say that the template is only applicable when the combobox is closed and the text will appear. When it is open, it displays the usual items in a comboboxes, if it is closed, it will display the display text of all selected teachers. thanks – user742102 Jun 13 '17 at 07:35
  • Yes, exactly that is what you have to do. You have to use template selector to decide which template to show at a run time. this link will help you do it. https://stackoverflow.com/questions/4672867/can-i-use-a-different-template-for-the-selected-item-in-a-wpf-combobox-than-for Try solution provided in this link and let me know about your progress. – Naresh Ravlani Jun 13 '17 at 07:42
  • I have updated my question. if you have time to look at it, feel free. thanks – user742102 Jun 13 '17 at 08:12
0

You could handle the Loaded event for the CheckBox in the ItemTemplate and set its Content property to a TextBlock of Inline elements, e.g.:

<ComboBox.ItemTemplate>
    <DataTemplate>
        <StackPanel Orientation="Horizontal">
            <CheckBox IsChecked="{Binding Path=IsSelected}" 
                        Background="{Binding Path=IsActiveColour}"
                        Foreground="{Binding Path=IsClashColour}" 
                        FontStyle="{Binding Path=EndDateFontStyle}"
                        Loaded="CheckBox_Loaded">
            </CheckBox>
            <Image Source="/SchoolEdgeTimetable;component/Images/greentick16x16.png" 
                       Margin="5,0,0,0" 
                       Visibility="{Binding Path=IsSpecialitySubjectVisibility}"></Image>
        </StackPanel>
    </DataTemplate>
</ComboBox.ItemTemplate>

private void CheckBox_Loaded(object sender, RoutedEventArgs e)
{
    CheckBox checkBox = sender as CheckBox;
    dynamic dataObject = checkBox.DataContext;
    string display = dataObject.Display;
    TextBlock textBlock = new TextBlock();
    //split the display string and add Inlines to the TextBlock as suggested by @Naresh Ravlani here...
    checkBox.Content = textBlock;
}
mm8
  • 163,881
  • 10
  • 57
  • 88
  • I tried this, it adds an inline texblock during combobox is open, not during closed, so this is not the answer. thanks. – user742102 Jun 14 '17 at 01:42
  • What do you mean by "not during closed"? Isn't this just a matter of handling another event like for example the DropDownClosed event? Creative thinking is a developers best friend... – mm8 Jun 14 '17 at 08:23
  • The combobx text is shown when it is closed while when it is opened, the items are displayed. I do have an event that calls dropdown closed, that is where I set the text by joinging all the selected item's display text. Anyway, nevermind, I just suggested to just add a prefix in each teacher's name coz it seems impossible to modify a template for text. thanks to all who tried to answer. – user742102 Jun 15 '17 at 03:15
-1

Add a datatrigger that changes your font to Italic:

<DataTrigger Binding="{Binding IsDefault}" Value="1">
    <Setter Property="FontStyle" Value="Italic"/>
</DataTrigger>
Chrille
  • 1,435
  • 12
  • 26
  • But the teacher's name are appended together in only one string. pls see my code. So the IsDefault trigger will no longer work. This is a text and not an instance or object. thanks – user742102 Jun 13 '17 at 07:02