views:

39

answers:

2

Hi, I have created a custom ItemsControl called Toolbox. I want to be able to display images in that Toolbox - it is a part of a diagram designer.

My xaml looks like this:

<d:Toolbox ItemsSource="{Binding}">
                            <ItemsControl.ItemTemplate>
                                <DataTemplate>

                                    <Image Source="{Binding Library}"/>

                                </DataTemplate>

                            </ItemsControl.ItemTemplate>
                        </d:Toolbox>

and my ViewModel:

 public ObservableCollection<ElectricalLibrary> l = null;
        public ObservableCollection<Image> _images = null;
        public ObservableCollection<Image> Library

        {
            get
            {
                if (l == null)
                {
                    DataAccessLayerClass dc = new DataAccessLayerClass();
                    dc.LoadComponents();
                    l = dc.Library;
                    foreach (ElectricalLibrary lib in l) { 
                        Image finalImage = new Image();
                        finalImage.Width = 80;
                        BitmapImage logo = new BitmapImage();
                        logo.BeginInit();
                        logo.UriSource = new Uri(lib.url.ToString());
                        logo.EndInit();

                        finalImage.Source = logo;
                        MessageBoxResult result = MessageBox.Show(logo.UriSource.ToString());  

                        _images.Add(finalImage);
                    }



                }
                return _images;
            }
            set { _images = value; }
        }

Ands this is a resource file for Toolbox itself:

<Style TargetType="{x:Type s:Toolbox}">
        <Setter Property="SnapsToDevicePixels"
                Value="true" />
        <Setter Property="Focusable"
                Value="False" />
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate>
                    <Border BorderThickness="{TemplateBinding Border.BorderThickness}"
                            Padding="{TemplateBinding Control.Padding}"
                            BorderBrush="{TemplateBinding Border.BorderBrush}"
                            Background="{TemplateBinding Panel.Background}"
                            SnapsToDevicePixels="True">
                        <ScrollViewer VerticalScrollBarVisibility="Auto">
                            <ItemsPresenter SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}" />
                        </ScrollViewer>
                    </Border>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
        <Setter Property="ItemsPanel">
            <Setter.Value>
                <ItemsPanelTemplate>
                    <WrapPanel Margin="0,5,0,5"
                               ItemHeight="{Binding Path=DefaultItemSize.Height, RelativeSource={RelativeSource AncestorType=s:Toolbox}}"
                               ItemWidth="{Binding Path=DefaultItemSize.Width, RelativeSource={RelativeSource AncestorType=s:Toolbox}}" />
                </ItemsPanelTemplate>
            </Setter.Value>
        </Setter>
    </Style>

I store only the URLs of the images in the database, the images are stored on a disc. I take the entity object and create an image, add it into an ObservableCollection of images and bind Image control to LIbrary in xaml.

Obviously, the code does not work. But how to make it work? The list with images is loaded correctly.

Thanks for help.

+2  A: 

*EDIT* Right - I have managed to get the code to work after some changes. Change your Library property to return a list of Uri's set from your database Objects - make sure you actually return something. I suggest the following for your property (change it if you need a more robust property which doesnt refetch every time there is get...

public ObservableCollection<Uri> Library
{
    get
    {
        OberservableCollection<Uri> library = new OberservableCollection<Uri>();
        DataAccessLayerClass dc = new DataAccessLayerClass();
        dc.LoadComponents();

        foreach (ElectricalLibrary lib in dc.Library)
        {
            library.Add(new Uri(lib.url.ToString()));
        }

        return library;
    }

Then your XAML can look like this:

                      <d:Toolbox ItemsSource="{Binding Library}">
                            <ItemsControl.ItemTemplate>
                                <DataTemplate>

                                    <Image Source="{Binding}"/>

                                </DataTemplate>

                            </ItemsControl.ItemTemplate>
                        </d:Toolbox>

Doing this makes it work fine for me.

Original text left for historical reasons

You seem to be binding the image to the entire collection. If it is just a single list of images you need then the ItemsSource of you toolbox should be the Library collection with an image as part of the DataTemplate (I cant test this right now so it may not be 100% accurate code)

<d:Toolbox ItemsSource="{Binding Library}">
    <ItemsControl.ItemTemplate>
        <DataTemplate>
                <Image Source="{Binding}"/>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</d:Toolbox>
Leom Burke
I tried it but the Images are still not visible.
Enzomatric
a) Are the items appearing in your list (just not as images).b) if you use a standard ListBox for this does it work?
Leom Burke
a) not, no object appears there at allb) something appears but not an image - looks like an empty listbox
Enzomatric
if you have break point at the point where it returns the list from the getter does it contain any items - this code should fail as _images is null when you try to add to it.
Leom Burke
Yes, I noticed that too. However, removing if did not help. Could it be that my ItemsControl does not accept templates?
Enzomatric
However, when I tried something like this:<d:Toolbox ItemsSource="{Binding Library}"> <Image IsHitTestVisible="False" Stretch="Fill" ToolTip="Chart1" Source="{Binding Path=url}"/> </d:Toolbox>There is an object of the specified size but no image is visible.
Enzomatric
You shouldn't remove it - before you check if l is null, check if _images is null, if it is then create a new collection ( _images = new ObservableCollection();)
Leom Burke
I had two approaches: one when I created the ObservableCollection with Images and tried to set that as a ItemsSource of a Toolbox and another one when I got the objects from the database and bound the source property of an image to the correct path (like Source={Binding path=url}) but in both cases the object is there but no image is displayed. Are you sure the problem is not related to the resource file of the toolbox control?
Enzomatric
I am just testing it now with a mock-up. If you remove the style and datatemplate and make it a ListBox you should just get a list of strings (class names) I think.
Leom Burke
But if I do something like that (notice that the Library is now the set of database entities; I removed the images part):<d:Toolbox> <Image IsHitTestVisible="False" Stretch="Fill" ToolTip="Chart1" Source="{Binding Path=Library.url}"/> </d:Toolbox>It should show an image provided that the url is a correct url (and it is), right?
Enzomatric
no your missing how the binding of an itemscontrol works. You bind the actual itemsControl (in your case the toolbox) to the collection on the VM (Library in your case) In the DataTemplate for the image source then you can put <Image IsHitTestVisible="False" Stretch="Fill" ToolTip="Chart1" Source="{Binding url}"/>
Leom Burke
Yes, I'm doing it exactly in this way. Does it matter that I'm trying to display it in an Expander?
Enzomatric
That's the uri /Images/SymbolsLibrary/chart2.png. It says that the path is visible.
Enzomatric
thats not the code you pated in your comment - the code in the comment was wrong - what are you actually doing. Can you edit the question with all these comments in some sort of logical format as it is getting difficult to understand what you are trying to do and have tried. something to try would be to create a small app that mimics what you are doing and show where it goes wrong - you can then paste the code for that small app so we can test and try some changes.
Leom Burke
+1  A: 

Try this:

<d:Toolbox ItemsSource="{Binding Library}"> 
<Image Source="{Binding}"/>
Veer
Thanks for an answer. I tried it but the Images are not visible.
Enzomatric
How can this be the answer if it didnt work (Sorry Veer)
Leom Burke
@Leom Burke: Even if this was an answer, the same answer was given by you, a minute prior. I don't deserve this.
Veer