views:

145

answers:

0

System.Windows.Data Error: 43 : BindingExpression with XPath cannot bind to non-XML object.; XPath='CarModel/PercentFront/@Visible' BindingExpression:Path=/InnerText; DataItem='String' (HashCode=-671055389); target element is 'StackPanel' (Name='PnlPercentFront'); target property is 'Visibility' (type 'Visibility') CurrentCarConfig

My situation is a little unique. For my application, I need a shared XmlDataProvider. I'm using Prism, so in my Infrastructure assembly, I created a singleton class that looks like:

public sealed class CarConfigXML
{
    #region Private Fields
    const string fileName = "CarConfigControls.xml";
    static readonly CarConfigXML _instance = new CarConfigXML();
    static XmlDataProvider _carConfigProvider = new XmlDataProvider();

    #endregion

    #region Constructors

    // Explicit static constructor to tell C# compiler
    // not to mark type as beforefieldinit
    static CarConfigXML()
    {
        // Load the XML doc for our config if it's not already loaded.
        if (_carConfigProvider.Document == null)
        {
            XmlDocument doc = new XmlDocument();
            doc.Load(fileName);
            _carConfigProvider.Document = doc;
            _carConfigProvider.XPath = "/CarConfig";
        }

    }

    #endregion

    #region Public Methods


    #endregion

    #region Public Properties

    public static CarConfigXML Instance
    {
        get
        {
            return _instance;
        }
    }

    public XmlDataProvider Provider
    {
        get { return _carConfigProvider; }
    }

    #endregion

    #region Public Methods

    public bool Save()
    {
        if (_carConfigProvider == null || _carConfigProvider.Document == null)
            return false;
        else
        {
            _carConfigProvider.Document.Save(fileName);
            return true;
        }
    }

    #endregion
}

I have an editor window whose grids sets it's DataContext to Provider and everything works fine.

My problem stems from I need certain StackPanels in the Views to bind to this XmlDataProvider to set their Visibility property.

I created a sample piece of code and as long as I set the datacontext of the control, everything works.

However, in the Views, their DataContext's are set to their associated ViewModels and the stackpanels contain children what bind to other properties in the ViewModel so I can set a parents DataContext to just one public property in the ViewModel.

Here is the code I'm trying to get to work in a View:

<StackPanel x:Name="PnlPercentDiagonal" Visibility="{Binding Source=CurrentCarConfig, 
            XPath=CarModel/PercentDiagonal/@Visible,
            Converter={StaticResource BoolToVisibilityConv}}"  >

CurrentCarConfig is a public property that just points to the Provider of the CarsConfigXML.

I'm getting the error that XPath cannot bind to a non-XMLObject, so instead of having CurrentCarConfig return just the XMLDataProvider, I've tried having it return the XMLDataProviders Document as so.

public XmlDocument CurrentCarConfig
    {
        get { return CarConfigXML.Instance.Provider.Document; }
    }

I've also tried returning it's DocumentElement such as.

public XmlElement CurrentCarConfig
    {
        get { return CarConfigXML.Instance.Provider.Document.DocumentElement; }
    }

But I still get the same error.

In the Xaml, I've tried using Binding Source and Binding Path but neither work.

I have to be able to create this binding without setting the StackPanels DataContext specifically to CurrentCarConfig.

Here is a relevant portion of the XML I'm using:

<CarConfig xmlns="" Text="Car Model" Visible="True" IsExpanded="True" IsCheckBoxEnabled="False">

To summarize, I need to just bind the visibility property of a stackpanel to a Property in my ViewModel with code similiar to the following.