Dynamic values like digit at ResourceDictionary - c#

For example i have smth like this
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:sys="clr-namespace:System;assembly=mscorlib">
<sys:String x:Key="USERNAME_AUTH_CONTENT">User auth success</sys:String>
</ResourceDictionary>
and in code behind, sometimes, I use this
var text = findRes("USERNAME_AUTH_CONTENT");
Is it possible to make smth like this:
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:sys="clr-namespace:System;assembly=mscorlib">
<sys:String x:Key="USERNAME_AUTH_CONTENT">User %username auth success</sys:String>
</ResourceDictionary>
and at codebehind
var text = findRes("USERNAME_AUTH_CONTENT", "here is i want to paste username");
in the end I want see this: 'User AwesomeUserName auth success'
In c++ I can use %d for string. What about c# and resources?

C# uses {0}, {1}, etc, placeholders for string formatting.
declare xaml resource with a placeholder
<system:String x:Key="USERNAME_AUTH_CONTENT">User {0} auth success</system:String>
and use String.Format to apply formatting:
var text = FindResource("USERNAME_AUTH_CONTENT") as string;
if (text != null)
{
text = String.Format(text, "AwesomeUserName");
}
note also that you can use format string directly from xaml:
<TextBlock Text="{Binding Source='AwesomeUserName', StringFormat={StaticResource USERNAME_AUTH_CONTENT}}"/>
(Source='AwesomeUserName' is just an example, if you have a view model, then use Binding Path=SomeProperty)

Related

How to get the actual object of StaticResource from codebehind without using TryFindResource?

I have used a StaticResource in XAML file. I have named the StaticResource using x:Name. Now I want to access the actual object of the StaticResource.
Here are the files:
In XAML file:
<Window x:Class="MyProject.MainWindow"
...
Title="MainWindow" Height="350" Width="525">
<Grid>
<StaticResource ResourceKey="MyButtonResource" x:Name="MyResource" />
</Grid>
</Window>
In Code-behind CS file:
Button buttonFromStaticResource = MyResource.SomeProperty as Button;
Here, I need something like SomeProperty or any method to get the actual object (in this case, it is a Button object).
Edit:
A way to get the object is to use TryFindResource:
Button buttonFromStaticResource = this.TryFindResource("MyButtonResource") as Button;
But this solution involves a string parameter. Any better solution than this so that I can use MyResource directly (by leveraging x:Name in XAML file), without using any string?
How to read static Resource in c#, Check a below code
<Window x:Class="MyProject.MainWindow"
...
Title="MainWindow" Height="350" Width="525">
<Grid>
<StaticResource ResourceKey="MyButtonResource" x:Name="MyResource" />
</Grid>
</Window>
c#
var currentResources= this.Resources["MyButtonResource"];

which way should i define Resource Dictionaries to keep my code clean?

I am new to WPF. My requirement is to implement the styling in a clean way. Styling includes fonts, colors, layouts, size,. etc.
Sample implementation with style is shown above. Requirement is in a window if its a form which receives input from user, common style needs to there like label has to right aligned, textbox has to be left aligned and some width and some properties and foreground property too.
My implementation
I made a separate assembly (because not only for this purpose it includes other user controls, styles, resources) which has a Layout.Xaml resource dictionary and in it all styles are defined.
Then a dependency property is created and through that the dictionary is linked as shown below.
<Window xmlns:MvvmLibsTests="clr-namespace:CreativeEye.TestConsole.MvvmLibsTests"
x:Class="CreativeEye.TestConsole.MvvmLibsTests.StyleTestView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="SyleTestView" Height="408" Width="706"
WindowStartupLocation="CenterScreen"
xmlns:Styles="clr-namespace:CreativeEye.MvvmLibs.Behaviours;assembly=CreativeEye.MvvmLibs">
<!--<Grid>-->
<Grid Styles:SetLayout.Resources="{StaticResource FormLayoutStyle}">
</Grid>
</Window>
In that FormLayoutStyle has value
<s:String x:Key="FormLayoutStyle">pack://application:,,,/CreativeEye.MvvmLibs;component/Resources/Layout.xaml</s:String>
in App.Xaml of the application.
The code for dependency property is
public static readonly DependencyProperty ResourcesProperty = DependencyProperty.RegisterAttached(
"Resources",
typeof(string),
typeof(SetLayout),
new PropertyMetadata("", new PropertyChangedCallback(CallBack)));
private static void CallBack(DependencyObject obj, DependencyPropertyChangedEventArgs e)
{
var layoutGridStylePath = e.NewValue;
if (layoutGridStylePath == null)
{
return;
}
var uri = new Uri((string)layoutGridStylePath, UriKind.RelativeOrAbsolute);
var grid = obj as FrameworkElement;
if (grid == null)
{
return;
}
grid.Resources.Source = uri;
}
And i achieved the result.
But i wanted to know is it a good way ?
and also i read some thing about memory leaks.
Reference links link 1, link 2.
I was more confused. I couldn't understand properly.
Can anyone please say in my implementation such memory leak problem will be der ?
Generally i use resources this way, but binding to c# code is also not at all a bad approach.
<Window x:Class="WPFDemo.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300">
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary
Source="Resources/MyResourceDictionary.xaml">
</ResourceDictionary>
<ResourceDictionary
Source="Resources/OthersStyle.xaml">
</ResourceDictionary>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>
<Grid>
<Image Source="/Images/logo.jpg"></Image>
</Grid>
</Window>

Set resource string to XAML

I know how to set string from resource
<TextBlock x:Uid="Text1"/>
where Text1.Text is "Hello"
But I want to do like this
<TextBlock Text = {something here to get GreetingText}/>
where GreetingText is "Hello"
So that I may get the same string from code also as
var loader = new Windows.ApplicationModel.Resources.ResourceLoader();
var string = loader.GetString("GreetingText");
Include this
xmlns:system="clr-namespace:System;assembly=mscorlib"
Have a resource of system:string like this.
<Window.Resources>
<system:String x:Key="GreetingText">Hello</system:String>
</Window.Resources>
and use it in xaml as
<TextBlock Text="{StaticResource GreetingText}" />
and use it in code behind as
string s = (string)objectofMainWindow.Resources["GreetingText"];
Edit: Answer to your comment
Its this way. Resource Dictionary is inside Window.Resources
<Window
xmlns:system="clr-namespace:System;assembly=mscorlib"
Your Rest namespaces
/>
<Window.Resources>
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:ATTFamilyMap.strings">
<system:String x:Key="GreetingText">Hello</system:String>
</ResourceDictionary>
</Window.Resources>
Your Code
</Window>
Nikhil's answer is on the right track, but is right for other platforms.
For windows 8, you need to do the following in your resource directory:
<x:String x:Key="MyString">This is a resource</x:String>
In your xaml:
<TextBlock Text="{StaticResource MyString}"/>
In code:
string myString = (string)(App.Current.Resources["MyString"]);

How to add comments into a Xaml file in WPF?

I used this syntax as I found online but it throws an error:
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
<!-- Cool comment -->
xmlns:System="clr-namespace:System;assembly=mscorlib"
'Name cannot begin with the '<' character, hexadecimal value 0x3C.
Line 4, position 5.' XML is not valid.
I assume those XAML namespace declarations are in the parent tag of your control? You can't put comments inside of another tag. Other than that, the syntax you're using is correct.
<UserControl xmlns="...">
<!-- Here's a valid comment. Notice it's outside the <UserControl> tag's braces -->
[..snip..]
</UserControl>
Found a nice solution by Laurent Bugnion, it can look something like this:
<UserControl xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:comment="Tag to add comments"
mc:Ignorable="d comment" d:DesignHeight="300" d:DesignWidth="300">
<Grid>
<Button Width="100"
comment:Width="example comment on Width, will be ignored......">
</Button>
</Grid>
</UserControl>
Here's the link:
http://blog.galasoft.ch/posts/2010/02/quick-tip-commenting-out-properties-in-xaml/
A commenter on the link provided extra characters for the ignore prefix in lieu of highlighting:
mc:Ignorable=”ØignoreØ”
You can't insert comments inside xml tags.
Bad
<Window xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
<!-- Cool comment -->
xmlns:System="clr-namespace:System;assembly=mscorlib">
Good
<Window xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:System="clr-namespace:System;assembly=mscorlib">
<!-- Cool comment -->
Just a tip:
In Visual Studio to comment a text, you can highlight the text you want to comment, and then use Ctrl + K followed by Ctrl + C. To uncomment, you can use Ctrl + K followed by Ctrl + U.
You cannot put comments inside UWP XAML tags. Your syntax is right.
TO DO:
<xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:System="clr-namespace:System;assembly=mscorlib"/>
<!-- Cool comment -->
NOT TO DO:
<xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
<!-- Cool comment -->
xmlns:System="clr-namespace:System;assembly=mscorlib"/>
For anyone learning this stuff, comments are more important, so drawing on Xak Tacit's idea (from User500099's link) for Single Property comments, add this to the top of the XAML code block:
<!--Comments Allowed With Markup Compatibility (mc) In XAML!
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:ØignoreØ="http://www.galasoft.ch/ignore"
mc:Ignorable="ØignoreØ"
Usage in property:
ØignoreØ:AttributeToIgnore="Text Of AttributeToIgnore"-->
Then in the code block
<Application FooApp:Class="Foo.App"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:ØignoreØ="http://www.galasoft.ch/ignore"
mc:Ignorable="ØignoreØ"
...
AttributeNotToIgnore="TextNotToIgnore"
...
...
ØignoreØ:IgnoreThisAttribute="IgnoreThatText"
...
>
</Application>

wpf image resources and changing image in wpf control at runtime

I would like to know exactly how to dynamically use a Dictionary Resource in the C# code behind - ie.. I would like to load images at runtime from an image resource within a dictionary
I have a program that has 3 images in a WPF Dictionary - these are images set as image resources.
Then in the code behind of my WPF Window I want to load any one of the three images based on user initiated events.
There is no real code I have to show as nothing that I have done works.
Ideas?
First, make sure you've defined your image resources like this:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<ImageSource x:Key="image1">images/image1.jpg</ImageSource>
<ImageSource x:Key="image2">images/image2.jpg</ImageSource>
</ResourceDictionary>
Secondly, I'm assuming that your WPF dictionary is in its own file. Now you have to make sure you've merged your dictionary into your main window's XAML (skip this step if your resource dictionary is defined inside of the window's XAML). In your window's XAML file, make sure you have something like this:
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="myDictionary.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>
Now, in your code-behind, you can use the FindResource() method to locate your image resource by it's key name (the value of the x:Key attribute on the ImageSource in the resource dictionary) like so:
imageControl.Source = (ImageSource)FindResource("image1");
Hope this helps!
This is an addition to the accepted answer:
When working within a ViewModel from MVVM, make sure to use the FindResource from the view where the resource directory is added.
<Window x:Class="My.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:ViewModels="clr-namespace:My.ViewModels"
Title="USA Hockey Player Evaluation tool"
Icon="/USAHockeyPlayerEval;component/View/Images/HET.ico"
SizeToContent="WidthAndHeight"
MinHeight="500px" MinWidth="800px">
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Images.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>
<Window.DataContext>
<ViewModels:MainWindowMV/>
</Window.DataContext>
<StackPanel>
<Menu>
<MenuItem Header="File">
<MenuItem Header="Save"></MenuItem>
My view in this case is a window (I know not correct MVVM ;-) )
Image img = new Image();
img.Source = (ImageSource)WindowReference.FindResource("Pluse");
Here the WindowReference is a reference to My.MainWindow.

Categories

Resources