tags:

views:

41

answers:

2

I'm trying to follow this little tutorial, but I keep getting this exception.

The relevant XAML looks like this:

    <StatusBar Margin="0,288,0,0" Name="statusBar" Height="23" VerticalAlignment="Bottom">
        <StatusBar.DataContext>
            <m:MainWindow />
        </StatusBar.DataContext>
        <TextBlock Name="statusText" Text="{Binding Path=StatusBarText, NotifyOnTargetUpdated=True}" DataContext="{Binding}">
            <TextBlock.Triggers>
                <EventTrigger RoutedEvent="Binding.TargetUpdated">
                    <BeginStoryboard>
                        <Storyboard>
                            <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="Opacity">
                                <EasingDoubleKeyFrame KeyTime="0" Value="0"/>
                                <EasingDoubleKeyFrame KeyTime="0:0:0.25" Value="1"/>
                                <EasingDoubleKeyFrame KeyTime="0:0:4" Value="1"/>
                                <EasingDoubleKeyFrame KeyTime="0:0:5" Value="0"/>
                            </DoubleAnimationUsingKeyFrames>
                        </Storyboard>
                    </BeginStoryboard>
                </EventTrigger>
            </TextBlock.Triggers>
        </TextBlock>
    </StatusBar>

I'm guessing I'm getting the StackOverflowException because I'm trying to use MainWindow as the DataContext. I want to use the MainWindow because it seems like a logical place to put my StatusBarText property,

public partial class MainWindow : Window
{
    public string StatusBarText { get; set; }

It makes it easier to access in my code-behind event handlers.

What am I supposed to do then? Where am I supposed to put this property? Or is there a way to set the DataContext to "this" so that it doesn't create a new instance of MainWindow and just refers to itself?

+1  A: 

Ideally your properties which you will bind to should live within a ViewModel following the MVVM pattern, abstracting themselves away from the View. Since that is not your question however we shall move along...the DataContext is inherited from its parent. Therefore if the StatusBar lives in the Window, which I am pretty certain it does, it will already be inheriting the DataContext from the Window. You are essentially trying to bind a UI component using a UI component (Window) as your source for the DataContext. Far from ideal...here is an overview of the MVVM pattern...

Aaron
He will inherit the DataContext from the window only if it is set for the Window, and is not reset by using the DataContext property on the UIElement itself (which his does).
Wonko the Sane
I guess I can throw the StatusBarText into its own ViewModel.. just seemed overkill for something so simple, and for only one element.
Mark
@Wonko Correct, which is where his StackOverFlowException was coming from...which is what he would need to remove to then take a different approach.
Aaron
@Mark Call it a ViewModel, call it MyFancyClassThatIsNotAWindow...it was just the point that following the odd design choices was leading you into the Exception...
Aaron
+2  A: 

I generally set my DataContext in code-behind, in the constructor (I usually use MVVM, but have used a window in small temp projects):

public MainWindow()
{
    statusBar.DataContext = this;
}

Note that in your shown code example, you will only get your initial StatusBarText value, because you are not implementing INotifyPropertyChanged.

Wonko the Sane
Perfect! Good call on the `NotifyPropertyChanged` too.. I discovered I could set the `DataContext` to `this` in the code-behind a second before you posted it, but then I ran into the problem you mentioned. Easy enough to notify though~!
Mark