fsprojects / FsXaml

F# Tools for working with XAML Projects
http://fsprojects.github.io/FsXaml/
MIT License
171 stars 48 forks source link

Unable to find the ResourceDictionary #18

Closed casbby closed 9 years ago

casbby commented 9 years ago

Hi,

I have the following app.xaml

<Application xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" StartupUri="MainWindow.xaml"

<Application.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="Telerik.Windows.Controls.xaml" />
        </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>
</Application.Resources>

The Telerik,Windows.Controls.xaml is at the root folder and above the app.xaml. (The same app.xaml file has no problem in a C# project). however in Fsharp project fails with

System.Windows.Markup.XamlParseException occurred Message: A first chance exception of type 'System.Windows.Markup.XamlParseException' occurred in FsXaml.Wpf.dll Additional information: 'Set property 'System.Windows.ResourceDictionary.Source' threw an exception.' Line number '10' and line position '37'.

at App().Root.Run()

Am i missing something here? also tried to use the applicationreources.xaml from the the demo as a test. same error is produced. environment F#3.0 VS2013

ReedCopsey commented 9 years ago

Try using a fully qualified Pack URI for the Source tag. It's likely that will solve the issue.

The main problem is often because we load the XAML at runtime, where a C# project pre-compiles to BAML. In theory, it should work the same, but in practice, there are some significant differences in terms of resource locations/resolution. Using full pack uri (with the assembly name) will often solve the issue.

-Reed

casbby commented 9 years ago

Hi Reed,

I have changed the Resource URI to be

<Application

xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

StartupUri="MainWindow.xaml"

>

<Application.Resources>

    <ResourceDictionary>

        <ResourceDictionary.MergedDictionaries>

            <ResourceDictionary

Source="pack://application:,,,Telerik.Windows.Controls;component/Telerik.Windows.Controls.xaml" />

        </ResourceDictionary.MergedDictionaries>

    </ResourceDictionary>

</Application.Resources>

however i am still getting the same error. The build action for the Telerik.Windows.Controls,xaml is set to resource

regards

Casbby

On Fri, Jan 2, 2015 at 4:28 AM, Reed Copsey, Jr. notifications@github.com wrote:

Try using a fully qualified Pack URI for the Source tag. It's likely that will solve the issue.

The main problem is often because we load the XAML at runtime, where a C# project pre-compiles to BAML. In theory, it should work the same, but in practice, there are some significant differences in terms of resource locations/resolution. Using full pack uri (with the assembly name) will often solve the issue.

-Reed

— Reply to this email directly or view it on GitHub https://github.com/fsprojects/FsXaml/issues/18#issuecomment-68492370.

casbby commented 9 years ago

Hi Reed,

it turns out the Pack URI needs to be set to relative, like

<Application.Resources>

    <ResourceDictionary>

        <ResourceDictionary.MergedDictionaries>

            <ResourceDictionary

Source="pack://application:,,,/Telerik.Windows.Controls.xaml" />

        </ResourceDictionary.MergedDictionaries>

    </ResourceDictionary>

</Application.Resources>

This actually works!. Thanks for your help. One more dumb question, Will Package like MvvM light wont work with Fsharp?

On Fri, Jan 2, 2015 at 8:31 PM, E Y zywcube@gmail.com wrote:

Hi Reed,

I have changed the Resource URI to be

<Application

xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

StartupUri="MainWindow.xaml"

>

<Application.Resources>

    <ResourceDictionary>

        <ResourceDictionary.MergedDictionaries>

            <ResourceDictionary Source="pack://application:,,,Telerik.Windows.Controls;component/Telerik.Windows.Controls.xaml"

/>

        </ResourceDictionary.MergedDictionaries>

    </ResourceDictionary>

</Application.Resources>

however i am still getting the same error. The build action for the Telerik.Windows.Controls,xaml is set to resource

regards

Casbby

On Fri, Jan 2, 2015 at 4:28 AM, Reed Copsey, Jr. <notifications@github.com

wrote:

Try using a fully qualified Pack URI for the Source tag. It's likely that will solve the issue.

The main problem is often because we load the XAML at runtime, where a C# project pre-compiles to BAML. In theory, it should work the same, but in practice, there are some significant differences in terms of resource locations/resolution. Using full pack uri (with the assembly name) will often solve the issue.

-Reed

— Reply to this email directly or view it on GitHub https://github.com/fsprojects/FsXaml/issues/18#issuecomment-68492370.

ReedCopsey commented 9 years ago

@casbby A full absolute Pack URI would have your assembly name, not Telerik.Windows.Controls - but should also work. Relative works fine, though, as you've discovered.

Packages like MVVM Light will work from F#. However, many of the C# MVVM libraries are based around C# language features (like Expression Trees, CallerMemberNameAttribute, etc), and are "clunky" when used from F#. I recommend looking at FSharp.ViewModule (used in many of the FsXaml demos) as an alternative for building your VM layer, as it uses F#-idiomatic mechanisms to implement INotifyPropertyChanged and INotifyDataErrorInfo (for validation).

casbby commented 9 years ago

Thank you very much for the advice and help. I just have one more question. I noticed the usage of quotation in the demos. I have been researching the usage and application of quotation but very few blog touched this part of fsharp. I know its a 'form' of reflection. What is main application for it? (I don't quite understand why fsharp viewmodel needs to use quotation for property)

Again thank you for your time and advice

On 3 Jan 2015, at 04:55, Reed Copsey, Jr. notifications@github.com wrote:

@casbby A full absolute Pack URI would have your assembly name, not Telerik.Windows.Controls - but should also work. Relative works fine, though, as you've discovered.

Packages like MVVM Light will work from F#. However, many of the C# MVVM libraries are based around C# language features (like Expression Trees, CallerMemberNameAttribute, etc), and are "clunky" when used from F#. I recommend looking at FSharp.ViewModule (used in many of the FsXaml demos) as an alternative for building your VM layer, as it uses F#-idiomatic mechanisms to implement INotifyPropertyChanged and INotifyDataErrorInfo (for validation).

— Reply to this email directly or view it on GitHub.

ReedCopsey commented 9 years ago

@casbby You can actually use strings for the names instead of the quotations. Using quotations allows us to tie the property name to the property itself instead of a "magic string". The quotation gets evaluated only once, and is used to pull out the property name to raise with INotifyPropertyChanged.

Many C# libraries do something similar with Expression Trees - this is just my version of it. The advantage is that a rename refactor (with F# Power Tools) will rename the quotation too - and it's a compile time error instead of a runtime error if there's a misspelling.

casbby commented 9 years ago

Thank you for the explanation and the great library.

Regards Casbby

On 3 Jan 2015, at 10:12, Reed Copsey, Jr. notifications@github.com wrote:

@casbby You can actually use strings for the names instead of the quotations. Using quotations allows us to tie the property name to the property itself instead of a "magic string". The quotation gets evaluated only once, and is used to pull out the property name to raise with INotifyPropertyChanged.

Many C# libraries do something similar with Expression Trees - this is just my version of it. The advantage is that a rename refactor (with F# Power Tools) will rename the quotation too - and it's a compile time error instead of a runtime error if there's a misspelling.

— Reply to this email directly or view it on GitHub.

RandyPJ commented 4 years ago

The same was happening to me. This is the solution: just add two dots before the slash of the folder name.

`

        <ResourceDictionary Source="../Styles/ComboBoxStyles.xaml" />
        <ResourceDictionary Source="../Styles/ButtonStyles.xaml" />
        <ResourceDictionary Source="../Styles/GroupBoxStyles.xaml" />
       <ResourceDictionary Source="../Styles/CheckBoxStyles.xaml" />

</ResourceDictionary.MergedDictionaries>`

Hope it helps other peoples.