0

I wonder if theres something wrong with my dependency property?

// In MarkdownEditor.xaml.cs, DataContext for MarkdownEditor.xaml
public string TextContent
{
    get { return (string)GetValue(TextContentProperty); }
    set { SetValue(TextContentProperty, value); }
}

public static readonly DependencyProperty TextContentProperty =
    DependencyProperty.Register("TextContent", typeof(string), typeof(MarkdownEditor), new UIPropertyMetadata(""));

When TextContent is set in XAML like

<me:MarkdownEditor TextContent="{Binding TextContent}" Options="{Binding Options}" />

It fails ... when I do

<me:MarkdownEditor TextContent="Hello world" Options="{Binding Options}" />

It works ... Is there something wrong? A similar thing seems to be happening to options


UPDATE 1

I notice that the binding with a normal text box works fine

<TextBox Text="{Binding TextContent}" />

FYI: In MarkdownEditor.xaml

<TextBox Text="{Binding TextContent}" 
        FontFamily="{Binding Path=Options.FontFamily}"
        FontSize="{Binding Path=Options.FontSize}"
        FontWeight="{Binding Path=Options.FontWeight}"
        Background="{Binding Path=Options.Background}"
        Foreground="{Binding Path=Options.Foreground}" />

UPDATE 2

Oh! I wonder if when I do

<me:MarkdownEditor TextContent="{Binding TextContent}" Options="{Binding Options}" />

Where does the properties TextContent & Options come from? MarkdownEditor's ViewModel?

UPDATE 3

Another few observations:

Barebones

<me:MarkdownEditor />

TextContent will be set to the value from MarkdownEditor's constructor

public MarkdownEditor()
{
    InitializeComponent();
    DataContext = this;
    TextContent = "From MarkdownEditor.xaml.cs";
}

Static Value

<me:MarkdownEditor TextContent="Static Value" />

The string "Static Value" is shown

Binding

<me:MarkdownEditor TextContent="{Binding Path=TextContent}" />

value from Dependency Property declaration is shown

public static readonly DependencyProperty TextContentProperty =
        DependencyProperty.Register(..., new UIPropertyMetadata("Default"));
Community
  • 1
  • 1
Jiew Meng
  • 84,767
  • 185
  • 495
  • 805
  • Tell us about the failure. What do you see versus what you expect to see? Are you seeing an empty string? Exception? Error message? – JeffFerguson Nov 19 '10 at 13:18
  • Is there a particular reason that you're using `UIPropertyMetadata` instead of `FrameworkPropertyMetadata`? That's a little unusual. Also, if you're in .Net 4, you should prefer `SetCurrentValue()` to `SetValue()` in `get_TextContent` – Greg D Nov 19 '10 at 13:19
  • How does it fail? Do you see a binding error in studio's output window? – Greg D Nov 19 '10 at 13:20
  • 1. What do you mean by "fails"? Do you mean that the viewmodel value shows in the UI, but it's not getting automatically pushed back when you edit? Or is the value not showing up in the UI in the first place? 2. If you run under the debugger, do any binding errors show up in the Output window? – Joe White Nov 19 '10 at 13:20
  • Hehehe, I'm sensing a theme in the comments! :D – Greg D Nov 19 '10 at 13:22
  • @JeffFerguson I see just an empty string, @Greg D, I see no errors – Jiew Meng Nov 19 '10 at 13:26
  • @Greg D, I am using `UIPropertyMetadata` as its from the VS snipplet. I'll check out `SetCurrentValue` too – Jiew Meng Nov 19 '10 at 13:27
  • Just updated my post (Update 1) – Jiew Meng Nov 19 '10 at 13:38
  • Try turning on diagnostics in the binding and checking out the detailed info. See: http://bea.stollnitz.com/blog/?p=52 – Greg D Nov 19 '10 at 13:42
  • Just put that in, I didn't get any errors/warning in output window, did I do something wrong? Or does it not produce any messages if there's no errors? I noticed too that the empty string is from the dependency property declaration `new UIPropertyMetadata("Default")` – Jiew Meng Nov 19 '10 at 14:05
  • Some new observations on what happens when TextContent is not set, set to s static string and a binding. (UPDATE 3) – Jiew Meng Nov 19 '10 at 14:18
  • What's the datacontext for your MarkdownEditor? are you binding the property's value to itself? – Greg D Nov 19 '10 at 14:25
  • @Greg D, yes, the data context of the usercontrol is the code behind, I solved the problem with @Daniel Rose's answer, basically, the datacontext of the markdown editor is overwriting ... – Jiew Meng Nov 20 '10 at 01:05
  • 1
    @Greg D, also could you answer my [other question about `SetCurrentValue()`](http://stackoverflow.com/questions/4230698/whats-the-difference-between-dependency-property-setvalue-setcurrentvalue) too? – Jiew Meng Nov 20 '10 at 01:13

5 Answers5

3

How are you setting the DataContext in MarkdownEditor.xaml for the bindings? The DataContext you set may get overwritten by the DataContext defined in your control which is using the MarkDownEditor. Thus, you should bind in MarkdownEditor.xaml using FindAncestor, looking for the UserControl (or whatever you have as root).

EDIT: It is a bit confusing what you have. I assume the following:

You defined a UserControl called MarkdownEditor, with MarkdownEditor.xaml and code-behind MarkdownEditor.xaml.cs. You set the DataContext of the control via this.DataContext = this; in the constructor in MarkdownEditor.xaml.cs or DataContext="{Binding RelativeSource={RelativeSource Self}}" on the root element in MarkdownEditor.xaml.

Secondly, you have a second UserControl/Window/whatever. Lets call it MyControl. It too has a DataContext which you set somehow. Then you bind TextContent as shown.

So, in MarkdownEditor, {Binding TextContent} refers to the DP in MarkdownEditor.xaml.cs. In MyControl, {Binding TextContent} refers to a property on your DataContext of MyControl. So you should check if you actually have such a property in MyControl's DataContext. Secondly, you should check if the DataContext in MarkdownEditor is what you expect, or if it got overwritten.

Daniel Rose
  • 17,233
  • 9
  • 65
  • 88
  • Yes, In my `MarkdownEditor.xaml.cs`, I have `DataContext = this`. The background of what I have is a UserControl `MarkdownEditor` then I have a Window to use as a test to run my usercontrol. And for that Window, I also set its `DataContext = this`. Ok maybe this is it, AHHH **TextContent="{Binding Path=TextContent, RelativeSource={RelativeSource AncestorType={x:Type Window}}}"** – Jiew Meng Nov 19 '10 at 14:30
  • After nearly the whole day, Thank you alot! – Jiew Meng Nov 19 '10 at 14:30
1

have you tried like this ?

<me:MarkdownEditor TextContent="{Binding Path=TextContent}" Options="{Binding Options}" />

(adding the "Path=")

David
  • 6,014
  • 4
  • 39
  • 55
  • Just tried, still doesn't work. Isnt it the same as `{Binding TextContent}`? – Jiew Meng Nov 19 '10 at 13:38
  • no it is not actually, it depends on the Context : in some cases, if the path has already been set before, then it will work without the "Path=", otherwise it won't. see this post for instance: http://social.msdn.microsoft.com/forums/en-US/wpf/thread/bc530773-4f6d-441a-8cf8-f9aa1f790f1a/ (it is a question of the Xaml knowing the elements from the code behind or not, as far as I could understand, and I myself had the issue with a "normal" - non-attached - property). In this case it indeed makes no difference though, but it was worth a try :) – David Nov 19 '10 at 14:06
1

I'm gonna get beaten up for this but :

Have-you tried this:

<TextBox Text="{Binding Path=TextContent}" 
        FontFamily="{Binding Path=Options.FontFamily}"
        FontSize="{Binding Path=Options.FontSize}"
        FontWeight="{Binding Path=Options.FontWeight}"
        Background="{Binding Path=Options.Background}"
        Foreground="{Binding Path=Options.Foreground}" />

(adding the "Path=" in your template this time) I know I'm sounding like a broken record, but this "Path=" gave me some headeache not so long ago, and I'm really wondering if your problem does not have something to do with this...

David
  • 6,014
  • 4
  • 39
  • 55
0

just try with elementname binding

eg. Give the Window x:name=MyWindow and use the elementbinding

<TextBlock Text="{Binding Path=Problem,ElementName=MyWindow}" />
Kishore Kumar
  • 21,449
  • 13
  • 81
  • 113
0

I don't know what the MarkdownEditor is or does, but I suppose that it's possible that the MarkdownEditor doesn't support two-way data binding by default. Specify that explicitly in your markup:

<me:MarkdownEditor TextContent="{Binding TextContent, Mode=TwoWay}" Options="{Binding Options}" />

Some XAML controls (such as TextBox) use two-way binding by default -- in other words, changes made in the data context are reflected in the control and changes made in the control are reflected in the data context. Other XAML controls use one-way binding by default. I am not sure what MarkdownEditor does by default, but, if it uses one-way binding by default, I could see how changes made in the control are not reflected in your data context. I would be interested to hear if explicitly setting the binding mode to TwoWay helps your situation.

JeffFerguson
  • 2,952
  • 19
  • 28
  • It does not seem to help. Also I found (in update 3) that if TextContent is set to a binding, the default value from the dependency property declaration is used. – Jiew Meng Nov 19 '10 at 14:20