Scenario
I have a class which looks something like this:
class GlobalAssemblyInfo
{
public const string AssemblyName = "MyAppName";
}
The class is NOT contained in a namespace.
I tried unsuccessfully to bind to this using the following code:
Text="{Binding GlobalAssemblyInfo.AssemblyName}"
Question
Is this possible, and if so, how would I accomplish this?
Why I Need This
Before I get any comments about only using bindings for dynamically changing content, let me explain why I need this.
I am creating an app which may need to undergo a rename due to trademark issues. I need to use the name in several places, such as "MyApp Contributors" or "MyApp Help." Using a binding would enable me to say merely Text="{Binding AppName, StringFormat='{}{0} Contributors'}".
You have two problems here. The first is that the way you're using the class in the binding is assigning it to the Path so it is looking for a property named GlobalAssemblyInfo on whatever your DataContext is. You instead need to use a static source and also expose the value as a property instead of a const. This uses the form:
{Binding Source={x:Static ns:Class.StaticProperty}}
The other problem is that you have no namespace to create your xmlns from in XAML. You should consider if you really need the class to not be namespaced but if you do you should be able to use the weird construction of
xmlns:myGlobal="clr-namespace:;assembly="
where you would then use myGlobal in the place of ns in the first example.
If you created a class that has no namespace, why don't you just put your assembly name in Resources in XAML or Resources in project so you can do binding in it with StringFormat
In your App.xaml.
Define something like this
<x:String x:Key="AssemblyName">Your Value</x:String>
or add a new resource file in your project and define it there.
So you can use it something like this
Text="{Binding Source={StaticResource AssemblyName}, Path=., StringFormat="{}}"
Related
I am trying to get multilingual translation("label or caption") string value for the given elementname in wpf.
For example; for elementname "txtDescription" ; my IValueConverter implementation will return with "Description" ; for another language will return different translation string(i.e. descripciĆ³n for Spanish) and the translation string will be Text=... of the same element.
I am new to wpf; I cant make it work. Is there any elegant way to do that with similiar manner as below.
<TextBlock Name="txtDescription" Text="{Binding Converter={StaticResource MultiLingualConverter} }"</TextBlock>
If this is not simple or requires more code then as an alternative sending "txtDescription" as an argument to MultiLingualConverter is acceptable but I dont now how to do that neither.
Definitely, you should build good localization support in your system, better then using converter for every string.
Until today, the best solution i have found and i almost always use it is this:
http://blogs.microsoft.co.il/tomershamam/2007/10/30/wpf-localization-on-the-fly-language-selection/
give it a try. good luck
You can pass the element name via the ConverterParameter property, this is an example of how it is used to pass a string to the converter.
However, WPF localization is more than returning different strings for different languages. You can read this article for more information and there is a Run Dialog Box example in the page to get you started.
Due to cyclical dependency restrictions you cannot reference a control inside itself or its descendants in the tree.
I would recommend you not to use converter for multilingual support. it is not a best way to do this.
got here for best way to do.
https://msdn.microsoft.com/en-us/library/ms745650(v=vs.110).aspx
No way to explain this issue except by example:
Say you have a custom UserControl with two DependencyPropertys, StatList Stats and string ImportantStat. The job of the user control is to display a table showing all of the values in Stats but with special visual treatment (like a pie chart) of the ImportantStat.
My instinct was to write a block of XAML that looked more or less like:
<PieChart Value="{Binding Path={Binding ImportantStat} }"/>
where the DataContext is prior set to Stats. So, the user passes in ImportantStat = "WinPercentage" and the pie chart binds to the WinPercentage Property of the stat line. But the user can just as easily pick some other Property to emphasize.
The problem (of course, you already know this, educated Stacker) is that you get an error message stating that you can't convert from Binding to string, which is what the outer Binding expects for Path. Though I haven't proven it to myself, I am guessing this is simply because Path is not a DependencyProperty.
So, is there any way to achieve my goal here? Feel free to break my assumptions in that first paragraph. Maybe, for example, ImportantStat can't be a string but must itself be a Binding.
Edit: Attempt #1 Failed
I was hoping that exposing from the code-behind a new DependencyProperty Binding ImportantStatBinding would allow me to rewrite the XAML as:
<PieChart Value="{Binding ImportantStatBinding, RelativeSource=... }"/>
...but to no avail. The indirect Binding is just stuck into Value itself with no attempts to resolve it.
My backup solution, which might be where this is headed, will be to just create the content inside the code-behind where I have access to ImportantStat directly and so can get away with a single Binding.
Far as I know, there is no way to concatenate data bindings in this way, without additional code. To put the problem more simply, we can have data binding (of course) of the form:
A --> B --> C
but you cannot have data binding of the form:
A --> B --> *A (*A indicates the target depends on the value of A)
because the relationships must be fixed.
It seems like it might be possible to create a Converter whose job is to convert a string into an arbitrary value by actually dereferencing a Binding using some additional context and that string as the property path. That sounds messy with type issues, so I chose the only other way I could think of:
I added a new DependencyProperty for the PieChart to the code behind and made sure that I constructed it at the appropriate times, so that the XAML could consume it. It's ugly, but it works. I just feel a little dead inside :) Hope someone finds this useful some day.
I've started creating a Windows Store App for Windows 8.1 and now I encountered a problem concerning localization.
I would like to display a string resource from a .resw file at design time, but every attempt to do so has failed, even though it works at runtime.
When using the x:Uid attribute, I still have to supply the Text property (i.e. for a TextBlock) and I don't like to write the text twice.
I also tried creating a property for the string on the viewmodel:
public string Title
{
get { return ResourceLoader.GetForCurrentView("Strings").GetString("MainView_Title"); }
}
This is working at runtime, but at design time it is blank.
So the question is, is there a way to display resources from a .resw file in the XAML-designer?
More specifically, does the ResourceManager class allow .resw files to be read at design time?
Thanks for your help,
Lucas
Old Method
So, there are a couple of things you can do.
The first (and simplest, given that you're using x:Uid already) is to just supply the text into the Text field. The x:Uid-related value will overwrite whatever is in there.
<TextBlock Text="MyText" x:Uid="MainView_Title"/>
The second method is to use the property like you already have, and then check to see if the app is in Design Time (through a couple of different methods), then return a constant value if it is and the Resource if it is not.
public string Title
{
if(ViewModelBase.IsInDesignTimeStatic) //Mvvm Light's easy accessor
return "My Text";
return ResourceLoader.GetForCurrentView("Strings").GetString("MainView_Title");
}
Hope this helps and happy coding!
Edit: There appears to be a new way to do this, at least as of Windows 8.1.
New Method
Create a class which references a ResourceLoader (similar to the property described above).
Create an indexed property accessor which accepts a string key and return the value from the ResourceLoader.
public class LocalizedStrings
{
public string this[string key]
{
get
{
return App.ResourceLoader.GetForViewIndependentUse().GetString(key);
}
}
}
In your App.xaml, define a StaticResource of this type.
<Application.Resources>
<ResourceDictionary>
<common:LocalizedStrings x:Key="Localized"/>
</ResourceDictionary>
</Application.Resources>
Now, when you want to access your property with entry key MainView_Title, use this. It's more verbose, but it should translate both in the designer and in the app itself.
<TextBlock Text="{Binding Source={StaticResource Localized}, Path=[MainView_Title]}" />
You can shuffle it around to be a bit more readable if you'd like, such as:
<TextBlock Text="{Binding [MainView_Title], Source={StaticResource Localized}}" />
This is an old thread, but since Nate provided such an elegant solution to the problem for Win8.1 I figured I'd ask here...
After much investigation and experimentation, Nate's solution does not appear to work for UWP apps for Win10 under VS2017 Community. The LocalizedString approach works just fine at runtime, but it appears
App.ResourceLoader.GetForViewIndependentUse().GetString(key);
refuses to return anything except String.Empty during design time. I've done a lot of experimenting and things like
ResourceContext.GetForViewIndependentUse().QualifierValues
Seem to be identical between runtime (working) and design time (not working).
I was wondering if anyone has encountered this and solved it. Nate? :)
Here's the setup I'd like to have for my Windows Phone app, using c# in visual studio 2010:
**MainPage.xaml** contains elements that have an attached property, whose values will be modifiable/savable by the user.
**MainPage.xaml.cs**
first Namespace is PhoneApp ,inside it is a nested namespace called MyNamespace that declares the dependency property. it works(Thanks, Daniel)
**SettingsSample.xaml** that will allow users to change the values of the attached property in MainPage.xaml for any element and automatically save the change.
**AppSettings.cs** a class that exactly reproduces the first listing in this tutorial:
http://msdn.microsoft.com/en-us/library/windowsphone/develop/ff769510%28v=vs.105%29.aspx
That page declares the same NameSpace as the MainPage.xaml.cs (PhoneApp), then a public class called AppSettings that is exactly like in the tutorial.
To join everything together, I did:
**MainPage.xaml**
xmlns:local="clr-namespace:PhoneApp.MyNamespace"
I needed this to use the attached property
<phone:PhoneApplicationPage.Resources>
<local:AppSettings x:Key="appSettings"></local:AppSettings>
</phone:PhoneApplicationPage.Resources>
Confusion begins. On the tutorial, they put this on the settings page, but I guess because their settings page is also the one including the elements with the properties that are bound to the saved settings. Mine are on the mainpage, so I put this here. To recap, My settings page will only use methods to change/save these values(and the methods are in AppSettings.cs). Also in the tutorial they add this:
xmlns:local="clr-namespace:SettingsSample"
to the Setting Page(where "SettingsSample" is the Namespace containing declaration/get-Set methods of savable settings) but, for the same reason, I tried to put it on the mainpage, but only one declaration of xmlns:local can be done. I tried several things to put them one after the other, but it doesn't work. This is the key to the two errors I'll list below.
Some elements of mainpage have this, for exemple:
local:MyClass.Son="{Binding Source={StaticResource appSettings}, Path=son1, Mode=TwoWay}" Style="{StaticResource pad}"
"Son" is the attached property
Ok, so I tried different different things but it never worked. The best I could get was in MainPage.xaml that it couldn't create an instance of AppSettings. Now it's different, I have the two errors.
-the type local:AppSettings was not found
-the tag AppSettings does not exist in xml namespace PhoneApp.MyNamespace.
I think this is because I didn't put the
xmlns:local="clr-namespace:PhoneApp"
But I already have
xmlns:local="clr-namespace:PhoneApp.MyNamespace"
and can't put both.(and to me, one is included in the other...) The reason I listed all the ins and out of the situation is because I kind of expect other troubles after I get through this.
I hope this message is clear enough for someone to help me. I spent so much time on it that I begin to loose my mind, so I hope there's no stupid mistake. Of course, I can add any information needed. Thank you for reading anyway!
These are XML namespace mappings. With the following:
xmlns:local="clr-namespace:PhoneApp"
The local part is the XML namespace, whilst PhoneApp is the namespace from your .NET code. With this definition in place you can then reference classes from this namespace in XML as follows:
<local:MyClassInPhoneAppNamespace/>
Because the local part is simply a name, you can change it to whatever you like:
xmlns:fish="clr-namespace:PhoneApp"
And use as follows:
<fish:MyClassInPhoneAppNamespace/>
This should mean that you no longer have collisions.
"local" in this case is simply a friendly name for the namespace you are referencing. It is completely interchangeable.
I was in need to import two local in same file as below
xmlns:local="clr-namespace:Generique.Views.Assets.Entries"
xmlns:local="clr-namespace:Generique.Views.Assets"
I just change the name and it works fine
xmlns:local="clr-namespace:Generique.Views.Assets.Entries"
xmlns:footer="clr-namespace:Generique.Views.Assets"
Perhaps it is something trivial but I am out of ideas...
Originally I wanted to add some features to PasswordBox. Because it is a sealed class, original properties have to be replicated, among them PasswordChar. Looks trivial, but when I started to set PasswordChar in Xaml, I could not get rid of parser exception.
At the end I simply defined a new property
public char MyProperty {get; set; }
and tried to set it in Xaml as follows:
<MyPasswordBox MaxLength="3" Password="xxx" MyProperty="c" />
I am getting an exception with the call stack looking like
at MS.Internal.XcpImports.CheckHResult()
at MS.Internal.XcpImports.ConvertStringToTypedCValue()
at MS.Internal.SilverlightTypeConverter.ConvertFrom()
at MS.Internal.FrameworkCallbacks.ConvertValueToPropertyType()
....
at MS.Internal.FrameworkCallbacks.SetValueToProperty()
at MS.Internal.FrameworkCallbacks.SetPropertyAttribute()
....
at System.Windows.Application.LoadComponent()
....
As far I can read it, the type conversion string -> char fails.
Note that whenever I'll change the type of MyProperty to string (for example), everything works.
Does anybody know how to implement char properties so that they can be set from Xaml?
Working on Windows Phone 7, perhaps that's the problem. (Limited SVL 3)
I can't verify this will work, but you can give it a go. The long form xaml syntax should work ok.
Add the following to your namespace imports
xmlns:sys="clr-namespace:System;assembly=mscorlib"
Then the following should work
<MyPasswordBox MaxLength="3" Password="xxx">
<MyPasswordBox.MyProperty>
<sys:Char>c</sys:Char>
</MyPasswordBox.MyProperty>
</MyPasswordBox>
The other solution is to look into type converters to apply to your property so that it'll convert the string for you. Type Convereters and XAML.