XAML converter in another project - xaml

Sorry for the F#...
I have a VS project with the following class:
namespace ABCCommonSilverlight
module ConvertersAndFormatters =
type FixedDecimalConverter () =
interface IValueConverter with
member this.Convert(value, targetType, parameter, culture) =
if value = null then
"N/A" :> obj
else
(decimalFormatter (value :?> Double)) :> obj
member this.ConvertBack(value, targetType, parameter, culture) = raise <| NotImplementedException()
And I've referenced this project in another project which has a XAML resources file which looks like this...
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:y="clr-namespace:ABCCommonSilverlight;assembly=ABCCommonSilverlight">
<y:ConvertersAndFormatters.FixedDecimalConverter x:Key="abcFixedDecimalConverter" />
</ResourceDictionary>
Without the ConvertersAndFormatters. in front of FixedDecimalConverter I get:
Exception "The type 'FixedDecimalConverter' was not found."
And with the "ConvertersAndFormatters." I get:
Exception "Cannot set properties on property elements."
Any idea what the right way to do this is?

The first thing I would try is moving the FixedDecimalConverter type out of the module, so that it's sitting directly in a namespace. (Right now the CLI and XAML see it as a nested class inside the module class.)

Related

Xamarin Style staticresource binding

would it be possible to databind a static resource in Xamarin Forms?
Something like
Style="{StaticResource {Binding foo, StringFormat='SomeStyle{0}'}}"
Thanks
What you probably want is a Value Converter that handles locating the StaticResource for you. Full Microsoft Documentation here.
On your XAML element, you'd do something like this:
<Entry Style="{Binding foo, Converter={StaticResource FooToStyleConverter}}"/>
Your converter would work something like this:
public class FooToStyleConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var someValue = (string)value; // Convert 'object' to whatever type you are expecting
// evaluate the converted value
if (someValue != null && someValue == "bar")
return (Style)App.Current.Resources["StyleOne"]; // return the desired style
return (Style)App.Current.Resources["StyleTwo"];
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
// Usually unused, but inverse the above logic if needed
throw new NotImplementedException();
}
}
Lastly, set up your converter as a Static Resource in App.xaml (or as a local resource on the page) so your page can properly reference it
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:DataBindingDemos">
<ContentPage.Resources>
<ResourceDictionary>
<local:FooToStyleConverter x:Key="FooToStyleConverter" />
....

Resource from DLL in other assembly

I'm creating an application that will be build in modules (DLL's). One of these DLL's provides the Strings for the application in different languages.
The DLL has following structure:
Languages (This is the project.)
Properties
References
Language.cs (Here I'm able to set the desired language from the application and has a GetText function that returns the String based on the set Culture.) Please let me know is this is a good approach.
Language.en-US.resx
Language.nl-BE.resx
So, from Languages.cs I'm able to get the desired String in C# from the resource files based on the set Culture.
Here is an example:
I set the culture to Dutch: Languages.Language.SetCulture("nl-BE");
I request the Dutch word for the resource Name: Language.GetText("Name");
It will return the String Naam.
That was C#. Xaml appears to be a bigger problem to get a Label.Text get the resource Name.
I added xmlns:l="clr-namespace:My.Languages.;assembly=My.Languages" to my xaml file, but this is as far as I got. I can't figure out a way how to have a similar Language.GetText("Name") in Binding.
My only solution at this point would be to bind every Label.Text to a property in my C# code and get the correct String from there. This will generate a lot of "not needed" binding/properties and would be hard to maintain.
Any suggestions?
My approach for Xaml would be to use a Converter that would call your Language.GetText(key);
e.g. XAML
<TextBlock Text={Binding FallbackValue='Naam', ConverterParameter='Name' Converter={StaticResource Translate}}" />
C#
public class TranslateConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (DesignerProperties.GetIsInDesignMode(new DependencyObject()))
return DependencyProperty.UnsetValue;
string localizedValue = string.Empty;
if (parameter is string)
{
localizedValue = Language.GetText(parameter as string);
return localizedValue;
}
else
{
return DependencyProperty.UnsetValue;
}
}
}

xaml Invalid Markup but still compiles/runs

I am trying to add a custom converter (Boolean to Visibility). The code for the converter is just fine. It seems to map ok. However, when I try and add it as a resource for a User Control I get an Invalid Markup which says "BooleanToVisibilityConverter was not found. Verify you are not missing an assembly and that all referenced assemblies have been built". Even with this Invalid Markup showing the project compiles and runs with no errors or crashes.
I am using Visual Studio 2013 on Windows 8.1
converter .h file:
#pragma once
using namespace Windows::UI::Xaml::Data;
using namespace Windows::UI::Xaml::Interop;
namespace BooleanConverter{
public ref class BooleanToVisibilityConverter sealed : IValueConverter
{
public:
virtual Platform::Object^ Convert(
Platform::Object^ value,
Windows::UI::Xaml::Interop::TypeName targetType,
Platform::Object^ parameter,
Platform::String^ language);
virtual Platform::Object^ ConvertBack(
Platform::Object^ value,
Windows::UI::Xaml::Interop::TypeName targetType,
Platform::Object^ parameter,
Platform::String^ language);
};
}
converter .cpp file:
#include "pch.h"
#include "BooleanToVisibilityConverter.h"
using namespace Platform;
using namespace Windows::Foundation;
using namespace Windows::UI::Xaml;
using namespace Windows::UI::Xaml::Interop;
using namespace Windows::UI::Xaml::Data;
Object^ BooleanConverter::BooleanToVisibilityConverter::Convert(Object^ value, TypeName targetType, Object^ parameter, String^ language)
{
auto boxedBool = dynamic_cast<Box<bool>^>(value);
auto boolValue = (boxedBool != nullptr && boxedBool->Value);
return (boolValue ? Visibility::Visible : Visibility::Collapsed);
}
Object^ BooleanConverter::BooleanToVisibilityConverter::ConvertBack(Object^ value, TypeName targetType, Object^ parameter, String^ language)
{
throw ref new Platform::NotImplementedException();
}
the xaml code:
<UserControl
x:Class="SimpleShop.JobItem"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:SimpleShop"
xmlns:converters="using:BooleanConverter"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" Width="1030" Height="Auto" Background="Black">
<UserControl.Resources>
<ResourceDictionary>
<converters:BooleanToVisibilityConverter x:Key="BooleanToCollapesdConverter"/>
</ResourceDictionary>
</UserControl.Resources>
I've tried changing the xmlns statement to:
xmlns:converters="clr-namespace:BooleanConverter"
but that throws up errors saying the BooleanConverter namespace can not be found
The really odd part is that if I delete the xmlns statement and re-type it in, intellisense says that the namespace can not be found. However if I simply copy and paste that line back over its self the error on the xmlns statement goes away.
How do I get rid of this Invalid Markup which doesn't seem to be invalid at all since it compiles and runs. Or have I missed something in implementing this converter? I am using MSDN as a reference (http://msdn.microsoft.com/en-us/library/ms747086(v=vs.110).aspx?cs-save-lang=1&cs-lang=csharp#code-snippet-1) and, to me, it doesn't look like I've implemented this wrong.
Please let me know if I need to supply more code but I believe this is everything that is relevant.
WinRT namespace lookup rules require that all namespaces published by a winmd live in a winmd with the same name (or a root namespace name). That is, a class named "MyNamespace.MySubNamespace.MyClass" must live in either MyNamespace.winmd or MyNamespace.MySubNamespace.winmd, otherwise it cannot be reliably found by all type loaders.
I think your issue is that your namespace is ::Converters, but your boolean converter class is probably hiding inside SimpleShop.winmd. I would try changing the namespace (and references) to SimpleShop::Converters and see if this resolves your issue.

Reference to current class xaml Windows Phone

I got the following code:
namespace SomeApp
{
public partial class MyClass : PhoneApplicationPage, IValueConverter
{
SOME METHODS...
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return true;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return true;
}
}
}
I would like to bind this class to a ValueConverter of a RadioButton. Is there any way to reference to the current class I'm working with? For example:
<phone:PhoneApplicationPage
x:Class="SomeApp.MyClass"
xmlns:local="clr-namespace:SomeApp">
<phone:PhoneApplicationPage.Resources>
<local:MyClass x:Key="myClass"/>
</phone:PhoneApplicationPage.Resources>
<RadioButton IsChecked="{Binding Converter={StaticResource myClass}}"/>
Thanks in advance =)
First using your page as a converter don't seem like a good idea, it's better practice to separate the converter fonctionality in a separate class. Particularly it would be a very bad idea to create a StaticResources of a converter created that way as it will use a lot of unessessary memory to create the whole page.
The only thing a converter can be binded in xaml is a StaticResource so you will not be able to do it in xaml but if you really want to do it you could do it by creating the binding from code behind (for example in the constructor of the page):
Binding binding=new Binding();
binding.Converter = this;
myRadioButton.SetBinding(CheckBox.IsCheckedProperty, binding);

The resource "ResourceName" could not be resolved error in WP8

I'm seeing an error trying to use a custom converter in my WP8 app.
I defined my converter in a namespace: standrighthere.Utilities:
namespace standrighthere.Utilities
{
public class NonNullVisibilityConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return value == null ? Visibility.Collapsed : Visibility.Visible;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
}
I then included it in the App.xaml manifest as so:
<Application.Resources>
<utilities:NonNullVisibilityConverter x:Key="NonNullVisibiltyConverter" />
</Application.Resources>
I then tried to use it in my phone application page like this:
<Button Visibility="{Binding Source={Binding User}, Converter={StaticResource ResourceKey=NonNullVisibilityConverter}}" />
However, it keeps giving the error:
Error 1 The resource "NonNonNullVisibilityConverter" could not be resolved.
I feel like I must be missing something really obvious here.
Looks like a simple typo. You called your converter "NonNullVisibiltyConverter" in the resources and NonNonNullVisibil*i*tyConverter in the binding.