Resource could not be resolved - c#

I got a error "The resource "ComponentTypeToStringConverter could not be resolved" Can someone tell me what am I doing wrong?
I've got this combo box:
<ComboBox SelectedItem="{Binding PcComponent.ComponentTypeName}" Grid.Column="1" Grid.Row="2" Grid.ColumnSpan="2">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Converter={StaticResource ComponentTypeToStringConverter}}"/> <!-- HERE I got a error The resource "ComponentTypeToStringConverter could not be resolved -->
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
Resource:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:c="clr-namespace:PcConfigurator.Converters">
<c:ComponentTypeToStringConverter x:Key="ComponentTypeToStringConverter"/>
</ResourceDictionary>
Converter (namespace PcConfigurator.Converters):
public class ComponentTypeToStringConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (!(value is ComponentType)) { return null; }
ComponentType type = (ComponentType)value;
switch (type)
{
//Do something
}
throw new InvalidOperationException("Enum value is unknown");
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotSupportedException();
}
}

In design time. Your resources are not yet compiled and the current XAML file that you have where it has the ComboBox can't see the ResourceDictionary.
Assuming your resources is defined in App.xaml then you should have no problems with it when you run it in runtime as it'll be able to find the key.
If you want to get rid of the error in design time then what you can do is on your XAML file where the ComboBox lives, you can add the ResourceDictioanry so that it'll be able to find it.
Assuming this is a Window and you have ResourceDictionary that is not defined in the App.xaml but as a separate file
<Window.Resources>
<ResourceDictionary Source=""/>
</Window.Resources>

Related

Accessing UserControl Resource Dictionary from code

I' am trying to read/load a UserControl Resources from my Home.xaml to a ResourceDictionary object so I can dynamicly display it inside content control and can't manage to find a solution.
I dont want to read it from my App.xaml, just the Home.xaml.
In my View folder I have Home.xaml:
<UserControl.Resources>
<converters:CheckBoxConverter x:Key="CheckBoxConv"></converters:CheckBoxConverter>
<DataTemplate x:Key="Punomoc">
<CheckBox Margin="10" Content="Izradi punomoć"
IsChecked="{Binding UnosIOS.Punomoc}">
</CheckBox>
</DataTemplate>
<DataTemplate x:Key="Naknada">
<CheckBox Margin="10,0" Content="Naplata naknade"
IsChecked="{Binding UnosIOS.NaplataNaknade}">
</CheckBox>
</DataTemplate>
</UserControl.Resources>
<Grid>
...
```
...
```
In my ConvertersFolder I have:
public class CheckBoxConverter : IValueConverter
{
private static readonly ResourceDictionary ControlResourceDictionary;
static CheckBoxConverter()
{
ControlResourceDictionary = new ResourceDictionary
{
Source = new Uri("pack://application:,,,/View/Home.xaml", UriKind.Absolute)
};
}
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
DataTemplate dataTemplate =ControlResourceDictionary["Punomoc"] as DataTemplate;
return dataTemplate;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
But its returning error:
''The invocation of the constructor on type 'IzdavanjeIOS.Converters.CheckBoxConverter' that matches the specified binding constraints threw an exception.' Line number '23' and line position '10'.'
Also tried with URI string : MyAppName/View/Home.xaml
I have setup MVVM and dont want to access resources from code-behind unless its the only choice, it seems to me that it should be possible like above, but maybe I am giving the wrong URI?

Binding inside of a binding

Ok I have a Observable collection containing string defined like so.
public ObservableCollection<string> OCGroundType { get; set; }
This collection is having resources key so what I'm trying to do is with this code
<ListBox HorizontalAlignment="Left" Height="110" Margin="156,23,0,0" VerticalAlignment="Top" Width="314" ItemsSource="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=OCGroundType}" >
<ListBox.ItemTemplate>
<DataTemplate>
<Label Content="{Binding Path=, Source={StaticResource Resources}}"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
So what I'm trying to do is give the path the value of the itemsource is that possible?
Edit
That's what the staticresource is 'binded' to , a resourceDictionary
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:cultures="clr-namespace:Marcam.Cultures"
xmlns:properties="clr-namespace:Marcam.Properties">
<ObjectDataProvider x:Key="Resources" ObjectType="{x:Type cultures:CultureResources}" MethodName="GetResourceInstance"/>
</ResourceDictionary>
What the ObjectType is 'binded' to is a method who return the current Resources.resx, If I've understanded well how it's work because I've based this code on this WPF Localization
It's not possible, because a Binding is not a DependencyObject, so its properties cannot be bound.
However, you could achieve the desired result by using a converter that fetches the appropriate value from the resources.
EDIT: first, you need a converter like this:
public class ResourceConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
string key = (string)value;
return Properties.Resources.ResourceManager.GetObject(key, culture);
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotSupportedException();
}
}
Then, declare an instance of this converter in the XAML resources:
<local:ResourceConverter x:Key="resourceConverter" />
And finally, just use this converter in your binding:
<Label Content="{Binding Path=., Converter={StaticResource resourceConverter}}"/>
Assuming Resources are mere string values declared under resources section of Window or UserControl, you can achieve that using IMultiValueConverter.
First of all you need to pass resource key and second ResourceDictionary of Window/UserControl wherever your resources are defined.
XAML will look like this:
<Label>
<Label.Content>
<MultiBinding Converter="{StaticResource ResourceToValueConverter}">
<Binding/>
<Binding Path="Resources" RelativeSource="{RelativeSource
Mode=FindAncestor, AncestorType=Window}"/>
</MultiBinding>
</Label.Content>
</Label>
Ofcourse you need to add instance of ResourceToValueConverter in XAML.
Second here goes your converter code:
public class ResourceToValueConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter,
System.Globalization.CultureInfo culture)
{
return ((ResourceDictionary)values[1])[values[0]];
}
public object[] ConvertBack(object value, Type[] targetTypes,
object parameter,
System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
UPDATE
As you edited the question to include that resource is ObjectDataProvider, you can modify converter code.
You have ObjectDataProvider in your converter which you can get and call it's method to get the resource file(.resx) file. Get string value from the resource file and return it.
var provider = ((ResourceDictionary)values[1])["Resources"] as ObjectDataProvider;
var output = provider.Data;
return // Get string from resource file and return it.

Implementing IValueConverter to convert string to image

I am currently trying to displaying images in my Windows 8 application. I have a method which populates a property of type List<string> with a number of paths to images. I wish to display these images on screen.
Thus, I have implemented a converter to go from string to image. However, I get the errors :
The name "StringToImageConverter" does not exist in the namespace
"using:TestApp.Converters".
'TestApp.Converters.StringToImageConverter' does not implement
interface member
'Windows.UI.Xaml.Data.IValueConverter.ConvertBack(object,
System.Type, object, string)'
'TestApp.Converters.StringToImageConverter' does not implement
interface member
'Windows.UI.Xaml.Data.IValueConverter.Convert(object, System.Type,
object, string)'
Here is the code from my Converter :
namespace TestApp.Converters
{
public sealed class StringToImageConverter : IValueConverter
{
public object Convert(object value, Type targetType,
object parameter, CultureInfo culture)
{
try
{
return new BitmapImage(new Uri((string)value));
}
catch
{
return new BitmapImage();
}
}
public object ConvertBack(object value, Type targetType,
object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
}
And from my XAML file :
<common:LayoutAwarePage
...
xmlns:converters="using:TestApp.Converters"
DataContext="{Binding RelativeSource={RelativeSource Self}}">
<Page.Resources>
<converters:StringToImageConverter x:Key="StringToImageConverter"> </converters:StringToImageConverter>
</Page.Resources>
...
<ItemsControl ItemsSource="{Binding Path=test}" Grid.Column="1" Grid.Row="3" Grid.ColumnSpan="4"
HorizontalContentAlignment="Stretch">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Image Source="{Binding Converter={StaticResource StringToImageConverter}}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
...
Should this work for displaying my images in the Windows 8 application? The List<string> of image paths is called test and is in the code behind of the xaml file.
Thanks very much for any and all help with this :)
Apparently there are two types of IValueConverters:
Windows.UI.Xaml.Data.IValueConverter
System.Windows.Data.IValueConverter
It sounds like your framework is expecting the former, while you're implementing the latter.
You probably also need to change this:
xmlns:converters="using:TestApp.Converters"
to this:
xmlns:converters="clr-namespace:TestApp.Converters"
Windows.UI.Xaml.Data.IValueConverter expects the last parameter to be a string, not a CultureInfo
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:s="clr-namespace:System.Collections;assembly=mscorlib"
xmlns:p="clr-namespace:System;assembly=mscorlib"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:Entities="clr-namespace:Entities;assembly=Entities"
mc:Ignorable="d"
x:Name="XXXXX"
x:Class="AAAA.XXXXX" Title="Seciones" Height="644.305" Width="909.579"
xmlns:c="clr-namespace:AAAA">
<Window.Resources>
<c:StringToImageConverter x:Key="stringToImageConverter"/>
</Window.Resources>
.....
</Window>

Binding a property to a style/resourcedictionary of a view

One of my views consists of 5 UserControls that each display data about a certain object. Let's say for example that the view displays the cows our company has, and on the screen cows 1 through 5 are displayed (each in their own UserControl).
What I want to do (but not sure is possible) is to bind the status of a cow to the style used in its respective UserControl. So we have a property status that could be ok, hungry, dead for example. In case the cow is ok I want to display a 'normal' style, if it's hungry I want the background to be red and if it's dead I want the text to be black and the fontsize increased.
I've added a simplified version of what I'm trying to achieve. My knowledge of WPF styles/resource dictionaries is still somewhat limited though.
What I basically want in code
A ViewModel with a Status property
class CowInfoViewModel : Screen
{
public string Name { get; set; }
public string Status { get; set; } //"ok", "hungry", "dead"
}
A View that retrieves a style or resourcedictionary
<UserControl x:Class="WpfModifyDifferentView.Views.CowInfoView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<!-- A reference to a ResourceDictionary with styles, that is bound to the 'Status' property -->
<StackPanel>
<TextBlock x:Name="Name" Text="Cow Name"/>
<TextBlock x:Name="Status" Text="Ok" />
</StackPanel>
</UserControl>
EDIT - Solution:
I did the following using Vale's answer:
In the xaml (reference to the converter):
<UserControl.Resources>
<Converters:CowStyleConverter x:Key="styleConverter" />
</UserControl.Resources>
In the xaml (elements):
<TextBlock x:Name="Name" Text="Cow Name" Style="{Binding Path=Style, ConverterParameter='TextBlockCowName', Converter={StaticResource styleConverter}}" />
The converter (note I left out the checks):
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
var status = value.ToString();
var styleName = parameter.ToString();
_resourceDictionary.Source = new System.Uri(string.Format("pack://application:,,,/Resources/ScreenI2Style{0}.xaml", status));
return _resourceDictionary[styleName];
}
Then I created multiple ResourceDictionaries with styles such as:
<Style x:Key="TextBlockCowName" TargetType="TextBlock">
<Setter Property="Foreground" Value="{StaticResource SomeBrush}" />
</Style>
You can bind UserControl Style property to Status and use a converter.
<UserControl x:Class="WpfModifyDifferentView.Views.CowInfoView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfModifyDifferentView"
Style="{Binding Path=Status, Converter={StaticResource myConverter}}">
<UserControl.Resources>
<local:MyConverter x:Key="myConverter" />
</UserControl.Resources>
I assume that your converter is in WpfModifyDifferentView directly.
Converter will look like this:
public class MyConverter : IValueConverter {
private ResourceDictionary dictionary;
public MyConverter() {
if (dictionary == null) {
dictionary = new ResourceDictionary();
dictionary.Source = new Uri("pack://application:,,,/WpfModifyDifferentView;Component/Resources/Styles.xaml");
}
}
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) {
switch (value.ToString()) {
case "ok":
return dictionary["myKeyForOkStyle"] as Style;
case "hungry":
return dictionary["myKeyForHungryStyle"] as Style;
case "dead":
return dictionary["myKeyForDeadStyle"] as Style;
default:
return null;
}
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) {
throw new NotImplementedException();
}
}
You need to specify the correct URI of course.

Can't get simple converter to work when using on a bound String

I have the following converter defined (C#):
class BodyValueConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
string s = value.ToString();
int prefixLength;
if (!int.TryParse(parameter.ToString(), out prefixLength))
return s;
return s.Substring(0, prefixLength);
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotSupportedException();
}
}
This will start at the start of the string being passed and will return the amount of characters I specify as a parameter.
In my XAML I have instanced the converter:
<local:BodyValueConverter x:Key="BodyValueConverter"/>
In attempting to use this converter in a textblock I get an error:
<DataTemplate x:Key="AppointmentTemplate">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Subject}"></TextBlock>
<TextBlock Text="{Binding Path=Subject, Converter={StaticResource BodyValueConverter}, ConverterParameter=1}"></TextBlock>
</StackPanel>
</DataTemplate>
The error is:
XAMLParseException: Provide value on 'System.Windows.Markup.StaticResourceHolder' threw an exception.
The first textblock works fine to display subject. The 2nd line is what gives me the exception.
What's the order of your objects in your XAML?
The Converter has to be defined prior to actually being used, so be sure your <Converter> is above your <DataTemplate> in your Resources
Another alternative is to switch to using a DynamicResource instead of a StaticResource, since a DynamicResource is evaluated when it is needed, not when the XAML is loaded
That error is usually thrown when it can't find the static resource you are looking for. You'll need to define that in your static resources.
<Window
.... snip ...
xmlns:local="clr-namespace:YourLocalNamespace"
<Window.Resources>
<local:BodyValueConverter x:Key="BodyValueConverter"/>
</Window.Resources>
.... snip ....
<DataTemplate x:Key="AppointmentTemplate">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Subject}"></TextBlock>
<TextBlock Text="{Binding Path=Subject, Converter={StaticResource BodyValueConverter}, ConverterParameter=1}"></TextBlock>
</StackPanel>
</DataTemplate>
</Window>
Note: This is when you are defining it in Window. You could define it elsewhere.
If this isn't the issue.... to find a more detailed explanation of what the parse error is... check the inner exception text.

Categories

Resources