Hello,
I have been trying to solve this simple problem now for a whole day without success and I simply dont see where I do the mistake. I have already checked the code of the FeatureBrowser and couln't get further.
I use the MVVM pattern and the xamdataGrid is filled through the "Properties" poperty on the MainViewModel:
public BindingList<PropertyRowViewModel> Properties { get; private set ; }
The PropertyRowViewModel is exposing the IsVirtual property.
I can see all the properties as columns populated on the grid without any problem.I would like to show an image according to whether IsVirtual is set or not and display that picture within the same column.
First I have created a field within the FieldLayouts of teh XamDataGrid:
<igDP:XamDataGrid.FieldLayouts><igDP:FieldLayout><igDP:FieldLayout.Fields><igDP:Field Name="IsVirtual" Label="IsVirtual"><igDP:Field.Settings><igDP:FieldSettings CellValuePresenterStyle="{StaticResource iconFieldCell}"/></igDP:Field.Settings></igDP:Field></igDP:FieldLayout.Fields></igDP:FieldLayout></igDP:XamDataGrid.FieldLayouts>
Within the Resources I have created the following:
<Style x:Key="iconFieldCell" TargetType="{x:Type igDP:CellValuePresenter}"><Setter Property="Template"><Setter.Value><ControlTemplate TargetType="{x:Type igDP:CellValuePresenter}"><StackPanel x:Name="stackPanel" Orientation="Horizontal"><Image Width="50" Source="{Binding Path=IsVirtual, Converter={StaticResource conv}, RelativeSource={RelativeSource Self}}">
And this is my converter:
public class IconConverter : IValueConverter{public object Convert(object value, Type targetType, object parameter, CultureInfo culture){if((bool)value){return new Uri(@"pack://xx.xx.Servicing.Client;,,/Resources/add2.png"); }else{return new Uri(@"pack://xx.xx.Servicing.Client;,,/Resources/arrow_left_blue.png"); }}public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture){return null;}}
I have set the Build action on both pictures as "Resource".1) I keep getting the error message on the output window:
System.Windows.Data Error: 39 : BindingExpression path error: 'IsVirtual' property not found on 'object' ''Image' (Name='')'. BindingExpression:Path=IsVirtual; DataItem='Image' (Name=''); target element is 'Image' (Name=''); target property is 'Source' (type 'ImageSource')
I also tried using Record.DataItem.IsVirtual instead with the same error message.
Why is it not working?
2) On another note is it possible within the converter to return the actual image directly from my resx, instead of getting its path to create a Uri? by using this:
return Properties.Resources.arrow_left_blue;
I would really appreciate it, if you would help me on these two questions.Many Thanks,Houman
Hi Alex,
I was just looking at your solution, while it works great for Image, but it doesn't work for BitmapImage.
<Style x:Key="iconFieldCell" TargetType="{x:Type igDP:CellValuePresenter}"><Setter Property="Template"><Setter.Value><ControlTemplate TargetType="{x:Type igDP:CellValuePresenter}"><StackPanel x:Name="stackPanel" Orientation="Horizontal"><Image Width="15"><Image.Source><BitmapImage DecodePixelWidth="15" UriSource="{Binding Path=DataItem.IsVirtual, Converter={StaticResource conv}}" /></Image.Source></Image></StackPanel></ControlTemplate></Setter.Value></Setter></Style>
Any idea why this doesn't work? I dont even get any Binding error on this. :-(
Help would be highly appreciated.
Kind Regards,Houman
Here is style using a ContentPresenter :
<Style TargetType="{x:Type igDP:CellValuePresenter}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type igDP:CellValuePresenter}">
<ContentPresenter Content="{Binding Path=Cells[Value].Value ,Converter={StaticResource conv}}"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
The converter can look something like :
public class ContentToImageConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
if (value == null || value.GetType() != typeof (int ))
return Binding .DoNothing;
}
else
switch ((int )value)
case 1:
return new Button () { Content = "Button 1" };
case 2:
return new CheckBox () { Content = "Checkbox 1" };
case 3:
return new RadioButton () { Content = "RadioButton 1" };
default :
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
throw new NotImplementedException ();
The converter will set the content of the cell to a Button, CheckBox and a RadioButton. Please note that WPF uses System.Windows.Controls.Image elements to display images. I believe, in the resources images are added as System.Drawing.Image so you would have to convert it to System.Windows.Controls.Image. Perhaps the Uri approach is more convenient.
Edit: sample attached
That you Alex. That was very helpful. The converter is now working.
I must admit though after I got it to work, I sat another 2 hours trying to figure out why the Uri creation was failing. What a monster! I finally got it work.
I am now a bit behind my schedule for delivery, otherwise I would have tried to make the ContentPresenter option work. It might have been the better option in order to not use the Uri at all.
You don't have an example by any chance from top of your head, do you? ;o)
Hello Houman,
The issue is coming from the binding expression you have set up. You have set the RelativeSource of the binding to Self. This means that the binding will look for IsVirtual property on the Image element itself (this is also what the binding error says).
There are couple of ways to resolve this
1. You do not need to set RelativeSource. The DataContext of the CVP is the DataRecord itself. All you need to do is change the binding to Path=DataItem.IsVirtual, Converter....
2. If you set RelativeSource ,make sure it is set to TemplatedParent. This will resolve it to the CellValuePresenter element. From there, you can use the following binding:
Path=Record.DataItem.IsVirtual, Converter...
3. Another way would be to set the RelativeSource and use the FindAncestor Mode, AncestorType-CellValuePresenter and use the same binding as 2). But this is really unnecessary as TemplatedParent mode is much simpler.
Regarding issue 2 : with your current setup, this will not be possible. You have set up the Source property of the Image to be bound with converter. This means that you would have to return a valid ImageSource object. What you can do is to use a ContentPresenter and use the same binding for its Content property. Then you would have to return an Image object with the converter.
Let me know if you have questions on these.