1

The Background

The summary of what I have is a UserControl MarkdownEditor. It contains a TextBox which has display properties like FontFamily, Background etc controlled by Bindings. It gets these values from an MarkdownEditorOptions class, which contains properties for each of these values. My code looks like below

In ShellView, showing how I might set display options for the TextBox in my MarkdownEditor

<me:MarkdownEditor>
    <me:MarkdownEditor.Options>
        <me:MarkdownEditorOptions Background="Red" />
    </me:MarkdownEditor.Options>
</me:MarkdownEditor>

In MarkdownEditor.xaml.cs, DataContext for MarkdownEditor (UserControl), the declaration for Options

public MarkdownEditorOptions Options
{
    get { return (MarkdownEditorOptions)GetValue(OptionsProperty); }
    set { SetValue(OptionsProperty, value); }
}

public static readonly DependencyProperty OptionsProperty =
    DependencyProperty.Register("Options", typeof(MarkdownEditorOptions), typeof(MarkdownEditor), new UIPropertyMetadata(new MarkdownEditorOptions()));

In MarkdownEditor.xaml : Showing the way TextBox binds to Option values

<TextBox Grid.Row="1" x:Name="txtEditor" AcceptsReturn="True" Text="{Binding Path=Content, UpdateSourceTrigger=PropertyChanged}" 
            FontFamily="{Binding RelativeSource={RelativeSource AncestorType={x:Type local:MarkdownEditor}}, Path=Options.FontFamily}"
            FontSize="{Binding RelativeSource={RelativeSource AncestorType={x:Type local:MarkdownEditor}}, Path=Options.FontSize}"
            FontWeight="{Binding RelativeSource={RelativeSource AncestorType={x:Type local:MarkdownEditor}}, Path=Options.FontWeight}"
            Background="{Binding RelativeSource={RelativeSource AncestorType={x:Type local:MarkdownEditor}}, Path=Options.Background, Converter={StaticResource colorToBrushConverter}}"
            Foreground="{Binding RelativeSource={RelativeSource AncestorType={x:Type local:MarkdownEditor}}, Path=Options.Foreground, Converter={StaticResource colorToBrushConverter}}" />

The MarkdownEditorOptions class

// MarkdownEditorOptions
public class MarkdownEditorOptions : ObservableObject
{
    protected FontFamily _fontFamily;
    protected int _fontSize;
    protected FontWeight _fontWeight;
    protected Color _background;
    protected Color _foreground;

    // Constructor, for default options
    public MarkdownEditorOptions()
    {
        _fontFamily = new FontFamily("Consolas");
        _fontSize = 14;
        _fontWeight = FontWeights.Bold;
        _background = new Color { R = 32, G = 32, B = 32, A = 255 };
        _foreground = new Color { R = 255, G = 255, B = 255, A = 255 };
    }

    public FontFamily FontFamily {
        get { return _fontFamily; }
        set {
            _fontFamily = value;
            RaisePropertyChanged("FontFamily");
        }
    }

    public int FontSize
    {
        get { return _fontSize; }
        set {
            _fontSize = value;
            RaisePropertyChanged("FontSize");
        }
    }

    public FontWeight FontWeight
    {
        get { return _fontWeight; }
        set {
            _fontWeight = value;
            RaisePropertyChanged("FontWeight");
        }
    }

    public Color Background
    {
        get { return _background; }
        set {
            _background = value;
            RaisePropertyChanged("Background");
        }
    }

    public Color Foreground
    {
        get { return _foreground; }
        set {
            _foreground = value;
            RaisePropertyChanged("Foreground");

        }
    }
}

The Problem

My TextBox in MarkdownEditor is always showing the defaults from constructor of MarkdownEditorOptions. In the simple XAML I've shown, the red background does not seem to be applied. Whats wrong?

[Update: 17 Nov: 4:25PM]

A Few Thoughts

I am thinking it has something to do with Path=Options.FontSize. Maybe this binding will track changes to Options instead of Options.FontSize?

UPDATE: 19 Nov

A few observations: If I use the control in a separate simple window

<Window ...>
    <Window.Resources>
        <me:MarkdownEditorOptions FontFamily="Arial" FontWeight="Normal" Background="Red" x:Key="options" />
    </Window.Resources>
    <Grid>
        <Grid.RowDefinitions ... />
        <Button Content="Options ..." Grid.Row="0" Click="Button_Click" />
        <me:MarkdownEditor Grid.Row="1" Options="{StaticResource options}" x:Name="markdownEditor" />
    </Grid>
</Window>

Things works fine, if I use it in a more complex setup. TabControl bound to ObservableCollection<TabViewModel>, it fails

<TabControl ... ItemsSource="{Binding TabsViewSource}" IsSynchronizedWithCurrentItem="True">

I tried with and without bindings. It seems the setters in MarkdownEditorOptions is run, as I added Debug.WriteLine() but the background etc does not update.

<DataTemplate DataType="{x:Type vm:EditorTabViewModel}">
    <!--<me:MarkdownEditor Options="{Binding RelativeSource={RelativeSource AncestorType={x:Type v:ShellView}}, Path=ViewModel.Options}" />-->
    <me:MarkdownEditor>
        <me:MarkdownEditor.Options>
            <me:MarkdownEditorOptions Background="Red" />
        </me:MarkdownEditor.Options>
    </me:MarkdownEditor>
</DataTemplate>
Jiew Meng
  • 84,767
  • 185
  • 495
  • 805

2 Answers2

2

Usually this is due to incorrect Path. Unfortunately, it will not raise an exception, you can try attaching vs debugger to your application and check for any binding error in debug log

ike3
  • 1,760
  • 1
  • 17
  • 26
  • Hmm I dont see any errors in the output window, is that where I am supposed to be looking at? In fact I see that my setters are being run, as I added `Debug.WriteLine` to them – Jiew Meng Nov 17 '10 at 14:41
0

This was fixed in another question of mine here on StackOverflow: Binding Setting Property but UI not updating. Can I debug within referenced project/control?

Community
  • 1
  • 1
Jiew Meng
  • 84,767
  • 185
  • 495
  • 805