The member "CurrentCulture" is not recognized or is not accessible - xaml

I have a Window with the following namespace
xmlns:sysglb="clr-namespace:System.Globalization;assembly=mscorlib"
that contains a textbox
<TextBox Text="{Binding Path=Price, Mode=TwoWay, StringFormat='C',
ConverterCulture={x:Static sysglb:CultureInfo.CurrentCulture}}"
MaxLines="1" TextAlignment="Right"/>
as per Gusdor's reply to StringFormat Localization issues in wpf which was working fine but now Visual Studio (2013) is giving me an "Invalid Markup" - The member "CurrentCulture" is not recognized or is not accessible error.
The Intellisense recognises and prompts sysglb:CultureInfo.CurrentCulture but as soon as I move away from the textbox I get the error.
Could some kind soul advise why this is happening and what I do to fix it?
Also how the XAML editor manages to recognize sysglb:CultureInfo.CurrentCulture yet the markup doesn't?
Cheers
Geoff

Can't remember where I got this from but it works
using System.Globalization;
using System.Windows.Data;
namespace SomeNamespace
{
/// <summary>
/// This class is a fudge because
///
/// xmlns:sysglb="clr-namespace:System.Globalization;assembly=mscorlib"
///
/// <TextBox Grid.Row="2" Grid.Column="1"
/// Text="{Binding Path=SelectedSupporterCategory.Price, Mode=TwoWay, StringFormat='C',
/// ConverterCulture={x:Static sysglb:CultureInfo.CurrentCulture}}"
/// UseLayoutRounding="True" MaxWidth="100" HorizontalAlignment="Left" MinWidth="100" HorizontalContentAlignment="Right"/>
///
/// is giving
/// Error 29 "The member "CurrentCulture" is not recognized or is not accessible."
///
/// Instead we use
///
/// <TextBox Grid.Row="2" Grid.Column="1"
/// Text="{CultureAwareBinding Path=SelectedSupporterCategory.Price, Mode=TwoWay, StringFormat='C',}"
/// UseLayoutRounding="True" MaxWidth="100" HorizontalAlignment="Left" MinWidth="100" HorizontalContentAlignment="Right"/>
///
/// </summary>
public class CultureAwareBinding : Binding
{
public CultureAwareBinding()
{
ConverterCulture = CultureInfo.CurrentCulture;
}
}
}

Changing the project target framework to .NET Framework 4.6 or higher solves the issue.
Go to solution explorer and right-click on the affected Project -> Properties -> Application -> Target framework.

found similar suggestion in this topic: WPF StringFormat={0:C} showing as dollars
my application was working when I launched it and diplayed values with correct culture formatting, but designer could not find CultureInfo.CurrentUICulture and crashed
I used static property in helper class
public static class WpfHelpers
{
public static CultureInfo CurrentCulture { get; set; }
}
and used it in bindings: ConverterCulture={x:Static helpers:WpfHelpers.CurrentCulture}
I set that property on Application startup
WpfHelpers.CurrentCulture =
Thread.CurrentThread.CurrentCulture =
Thread.CurrentThread.CurrentUICulture = new CultureInfo ...

Related

DataBinding and Incomplete Microsoft Documentation

Basically, I'm working through the Microsoft tutorial on WPF:
https://learn.microsoft.com/en-us/dotnet/opbuildpdf/framework/wpf/data/toc.pdf?branch=live
I get to page 8, and (in my opinion) Microsoft screwed up. They don't give any C# code-behind that is necessary to run the following XAML:
<DockPanel
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:c="clr-namespace:SDKSample">
<DockPanel.Resources>
<c:MyData x:Key="myDataSource"/>
</DockPanel.Resources>
<DockPanel.DataContext>
<Binding Source="{StaticResource myDataSource}"/>
</DockPanel.DataContext>
<Button Background="{Binding Path=ColorName}" Width="150" Height="30">
I am bound to be RED!</Button>
</DockPanel>
I follow their description as best as possible, but all I get is this following error message.
The name "MyData" does not exist in the namespace "clr-namespace:SDKSample".
I do what I'm supposed to do: create a c# file, using "Add New Item" and build it, but still that error code pops up again. To save people from having to look up the documentation, here's what they ask for:
Consider the following example, in which the binding source object is
a class named MyData that is defined in the SDKSample namespace. For
demonstration purposes, MyData class has a string property named
ColorName, of which the value is set to "Red". Thus, this example
generates a button with a red background.
I've looked in the various SDK's for this example, hoping I'd find the mysterious C# file somewhere, but alas I can't find it. It seems like Microsoft forgot a link. You know, even if it is somewhere in an SDK, it is extremely hard to find. As someone in a learning-mode, I'd hope that all the gritty details would be provided in the documentation, not just the quote from above, which doesn't go into any details as to where to put the C# file, how you are supposed to build so it will properly get registered as existing.
So, if anyone can find a nice description as to how to get the XAML code to work, by creating a C# class named "MyData" in a "SDKSamples" namespace, I'd be very appreciative.
the xaml works when you add the following:
namespace SDKSample
{
public class MyData
{
public Brush ColorName { get; set; } = Brushes.Red;
}
}
<Window x:Class="StackExchangeQuestion.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:StackExchangeQuestion"
mc:Ignorable="d"
xmlns:c="clr-namespace:SDKSample"
Title="MainWindow" Height="350" Width="525">
<DockPanel >
<DockPanel.Resources>
<c:MyData x:Key="myDataSource"/>
</DockPanel.Resources>
<DockPanel.DataContext>
<Binding Source="{StaticResource myDataSource}"/>
</DockPanel.DataContext>
<Button Background="{Binding Path=ColorName}" Width="150" Height="30">
I am bound to be RED!</Button>
</DockPanel>
</Window>
I'd like to add that Microsoft assumes that you have all the stuff between <Window x:Class and Width="525"> already there. It's kind of sloppy work to just leave out that massive detail in their documentation. Thanks to Milan for getting me to look at what should go inside the <Window>...</Window> part of the code.
Also, in the interest of completeness, the C# code:
using System.Windows;
using System.Windows.Media;
namespace StackExchangeQuestion
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
}
}
namespace SDKSample
{
public class MyData
{
public Brush ColorName { get; set; } = Brushes.Red;
}
}

System.Type as property of converter - only works with unused property in code behind

I have a IValueConverter that has a System.Type property which is set in XAML.
Converter:
internal class EnumTypeConverter : IValueConverter
{
public Type TypeToDisplay { get; set; }
public object Convert(object value, Type targetType, object parameter, string language)
{
return TypeToDisplay?.FullName;
}
public object ConvertBack(object value, Type targetType, object parameter, string language)
{
throw new NotImplementedException();
}
}
XAML:
<Page
x:Class="UWPSystemTypeConverterTest.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:converter="using:UWPSystemTypeConverterTest.Converter"
xmlns:enums="using:UWPSystemTypeConverterTest.Enum"
mc:Ignorable="d">
<Page.Resources>
<converter:EnumTypeConverter x:Key="Converter" TypeToDisplay="enums:CustomEnum" />
</Page.Resources>
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<TextBlock Text="{Binding Converter={StaticResource Converter}}" />
</Grid>
</Page>
When I run the application, I get following error:
Windows.UI.Xaml.Markup.XamlParseException: 'The text associated with
this error code could not be found.
Failed to create a
'UWPSystemTypeConverterTest.Converter.EnumTypeConverter' from the text
'enums:CustomEnum'. [Line: 14 Position: 56]'
If I add a property of type CustomEnum to the code- behind file, which is never used, the application works.
the changed code- behind- File:
public sealed partial class MainPage : Page
{
public CustomEnum WithThisPropertyTheAppWorks { get; set; }
public MainPage()
{
InitializeComponent();
this.DataContext = this;
}
}
The complete project for reproduction is here: https://github.com/SabotageAndi/UWPSystemTypeConverterTest
Line to uncomment is https://github.com/SabotageAndi/UWPSystemTypeConverterTest/blob/master/UWPSystemTypeConverterTest/MainPage.xaml.cs#L13
I suspect that an optimiser of UWP is causing this problem.
Is this really the case?
How can I fix the error without the unused property in the code-behind file?
Targeting UWP Build 10240, a viable work around is to add a dummy instance of the targeted enum in static resources of the page before instantiating the converter.
<Page.Resources>
<enums:CustomEnum x:Key="WorkAround">CustomEnumValue</enums:CustomEnum>
<converter:EnumTypeConverter x:Key="Converter" TypeToDisplay="enums:CustomEnum" />
</Page.Resources>
Info from a MSFT employee on a MVP mailing list:
This behaviour is a current limitation of UWP.
The XAML compiler and the runtime don't support System.Type- typed properties. So the needed metadata is not generated and the runtime can not convert the string to the type.
But because of the public properties on the code-behind, the compiler generates the needed metadata now. I am not that happy with the work around, but it is better than other solutions (e.g. a string property with the fullname to the type).

XBF Error with DataTemplate in Application.Resources

Universal Windows Platform app with Visual Studio 2015 (RTM)
I have a DataTemplate that is used in multiple pages of my app, so I'd prefer to write it once and access it from anywhere I need to. In order to make it accessible by any page, I write it in my App.xaml's <Application.Resources>:
<Application
x:Class="MyApp.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:MyApp"
xmlns:viewmodels="using:MyApp.ViewModels"
RequestedTheme="Light">
<Application.Resources>
<DataTemplate x:Key="DetailContentTemplate" x:DataType="viewmodels:DataViewModel">
...
</DataTemplate>
</Application.Resources>
The DataTemplate portion of the code above works just fine in an individual page, but of course that means I'd have to copy and paste it multiple times to other pages, which just isn't efficient. However, I get this error when I use the DataTemplate in App.xaml:
XBF generation error code 0x09c4
I've determined that it stems from the x:DataType="viewmodels:DataViewModel" (without this, and hence, without any bindings the code works just fine). Looking up the error results in next to nothing. Is there a convenient workaround/solution to being able to reuse a DataTemplate with bindings in a Universal Windows Platform/WinRT app, preferably in XAML?
EDIT: As requested, the code in full for App.xaml.cs:
namespace MyApp
{
/// <summary>
/// Provides application-specific behavior to supplement the default Application class.
/// </summary>
sealed partial class App : Application
{
/// <summary>
/// Allows tracking page views, exceptions and other telemetry through the Microsoft Application Insights service.
/// </summary>
public static Microsoft.ApplicationInsights.TelemetryClient TelemetryClient;
/// <summary>
/// Initializes the singleton application object. This is the first line of authored code
/// executed, and as such is the logical equivalent of main() or WinMain().
/// </summary>
public App()
{
TelemetryClient = new Microsoft.ApplicationInsights.TelemetryClient();
this.InitializeComponent();
this.Suspending += OnSuspending;
}
/// <summary>
/// Invoked when the application is launched normally by the end user. Other entry points
/// will be used such as when the application is launched to open a specific file.
/// </summary>
/// <param name="e">Details about the launch request and process.</param>
protected override void OnLaunched(LaunchActivatedEventArgs e)
{
Frame rootFrame = Window.Current.Content as Frame;
// Do not repeat app initialization when the Window already has content,
// just ensure that the window is active
if (rootFrame == null)
{
// Create a Frame to act as the navigation context and navigate to the first page
rootFrame = new Frame();
// Set the default language
rootFrame.Language = Windows.Globalization.ApplicationLanguages.Languages[0];
rootFrame.NavigationFailed += OnNavigationFailed;
if (rootFrame.Content == null)
{
rootFrame.Navigate(typeof(MasterDetailPage));
}
// Place the frame in the current Window
Window.Current.Content = rootFrame;
}
// Ensure the current window is active
Window.Current.Activate();
}
/// <summary>
/// Invoked when Navigation to a certain page fails
/// </summary>
/// <param name="sender">The Frame which failed navigation</param>
/// <param name="e">Details about the navigation failure</param>
void OnNavigationFailed(object sender, NavigationFailedEventArgs e)
{
throw new Exception("Failed to load Page " + e.SourcePageType.FullName);
}
/// <summary>
/// Invoked when application execution is being suspended. Application state is saved
/// without knowing whether the application will be terminated or resumed with the contents
/// of memory still intact.
/// </summary>
/// <param name="sender">The source of the suspend request.</param>
/// <param name="e">Details about the suspend request.</param>
private void OnSuspending(object sender, SuspendingEventArgs e)
{
var deferral = e.SuspendingOperation.GetDeferral();
//TODO: Save application state and stop any background activity
deferral.Complete();
}
}
}
You can find some explanation here from the latest build session at 20:10
You basically need to create a resource dictionary in XAML and attach a class to it. This class file is needed to allow the compiler to generate its code.
Depending on what you have to do and how you can change your code, you can still use the "old" {Binding} markup which will work as before.
<Application.Resources>
<DataTemplate x:Key="DetailContentTemplate">
<TextBlock Text={Binding myValue} />
</DataTemplate>
</Application.Resources>

Use MVVM Light View Model Locator with Child Window in Silverlight 4

I want to use the View Model Locator in a Child Window.
Problem is this don't work:
<controls:ChildWindow x:Class="Views.PopupViews.AddAlert"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="clr namespace:System.Windows.Controls;assembly=System.Windows.Controls"
DataContext="{Binding AddAlert, Source={StaticResource Locator}}>
I get the error:
Cannot find a Resource with the Name/Key Locator
There is no trick to binding a child window to a static view model using the locator pattern. My guess is your DataContext is wrong.
Check:
Make sure you have an "AddAlert" property defined in your locator class. Something like:
private static AddAlertViewModel _AddAlertViewModel;
/// <summary>
/// Gets the ViewModelPropertyName property.
/// </summary>
public static AddAlertViewModel AddAlertViewModelStatic
{
get
{
if (_AddAlertViewModel == null)
{
CreateAddAlertViewModel();
}
return _AddAlertViewModel;
}
}
/// <summary>
/// THIS PROPERTY IS WHAT YOU NEED TO REFERENCE IN YOUR XAML
/// </summary>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Justification = "This non-static member is needed for data binding purposes.")]
public AddAlertViewModel AddAlert
{
get
{
return AddAlertViewModelStatic;
}
}
And of course make sure your view model locator is instantiated in your App.xaml file:
<vm:MyModelLocator xmlns:vm="clr-namespace:MyAppNamespace" x:Key="Locator" />
Ok the reason why it don't works is my childWindow is created inside the ctor of an IApplicationService.
This popupService is declared in the App.xaml:
<Application.Resources>
<ResourceDictionary>
<vm:ViewModelLocator xmlns:vm="clr-namespace:Client.ViewModel" x:Key="Locator" />
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Assets/Styles.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
<Application.ApplicationLifetimeObjects>
<popup:myPopupService/>
</Application.ApplicationLifetimeObjects>
Apparently, the view was created before the app resources !

Silverlight: Data Binding: Using of Dependency Properties within a Row of a Collection

I have an collection + its structure:
public class FunctionListBindStructure : AttributeBase
{
public FunctionListBindStructure() : base(true) { }
//this represents one row of the collection
public MyFunction Function { get; set; }
public string Name { get; set; }
}
public class FunctionListBind : AttributeListBase
{
//this represents
public ObservableCollection<FunctionListBindStructure> FunctionList { get; set; }
public FunctionListBind()
: base(true)
{
FunctionList = new ObservableCollection<FunctionListBindStructure>();
}
public override IList GetList()
{
return FunctionList as IList;
}
}
This class makes usage of a framework, which generates a Dependency Property for the CLR property Function.DisplayName as "FunctionDisplayNameProperty".
In my example view I bind this collection to a ListBox
ListBox ItemsSource="{Binding MyModel.FunctionListBind.FunctionList}" Height="52" HorizontalAlignment="Left" Margin="136,157,0,0" Name="listBox1" VerticalAlignment="Top" Width="130" >
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding FunctionDisplayNameProperty, Mode=TwoWay}"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
The problem is now that only the last item of the collection is displayed in the list...the previous items are rendered only with space; although I am pretty sure (via debugger) that the dependendy properties (when they registered and their value set) of the previous rows shall have non-initial values. If I refer directly to the corresponding CLR property (Function.DisplayName) all works fine.
My question: Do I make here a design error? Are Dependency Properties not supposed to be used as a row type? I use the same pattern for non-collection and there it works. This is also the reason why I want to use the same approach for collections (I can use 90% of the exisitng codeline to generate and set the Dependeny Properties).
Thanks for any hints also how (if not a design error) to debug the Dependency Property binding.
It was just a bug of my framework coding. I have defined the dependency properties as an instance attribute, instead of a static one. Now all works fine.