1

I have this project where I would like to set some images to my screen by adding a custom control (inSignalLight) to a listbox (or some other control, I would just like to line them up). I have set the images in the custom controls and added them to a "ObservableCollection", but nothing shows up. Im really new to WPF, so not quite sure if the xaml is corrent... If there is a better way to do it then in a listbox, please tell me so too.

inSignalLights = new ObservableCollection<inSignalLight>();

Here is the xaml in the page that I would like to show the pictures in.

<Page x:Class="Project.Pages.MainPicView"
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
  xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
  mc:Ignorable="d" 

  HorizontalAlignment="Stretch"
  VerticalAlignment="Stretch"
  Background="Beige"
Title="MainPicView" d:DesignHeight="343" d:DesignWidth="676">

<Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
    <Label Content="Label" Height="30" HorizontalAlignment="Left" Margin="61,195,0,0" Name="label1" VerticalAlignment="Top" Width="164" />
    <ListBox ItemsSource="{Binding Path=inSignalLights}" Width="400" Height="25" Margin="0,0,0,0" VerticalAlignment="Top" HorizontalAlignment="Left">
        <ListBox.ItemsPanel>
            <ItemsPanelTemplate>
                <WrapPanel IsItemsHost="True"/>
            </ItemsPanelTemplate>
        </ListBox.ItemsPanel>
    </ListBox>
</Grid>
</Page>

Edit:

This is the xaml for the custom control

<UserControl x:Class="Project.CustomControls.inSignalLight"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         mc:Ignorable="d" 
         d:DesignHeight="16" d:DesignWidth="16">
<Grid>
    <Image Height="16" HorizontalAlignment="Left" Margin="0,0,0,0" Name="signalImage" Stretch="Fill" VerticalAlignment="Top" Width="16" />
</Grid>
</UserControl>

Edit:

for (int i = 0; i < inpins; i++)
        {
            InPin ip = iFace.getInPin(i);
            parent.insertNewSignalLight(ip);
        }

public void insertNewSignalLight(InPin ip)
    {
        inSignalLight isl = new inSignalLight(ip);
        isl.setLightOff();
        this.inSignalLights.Add(isl.signalImage);
    }
public void setLightOff()
    {
        setThreadSafeImage(signalImage);
    }

    private void gotLightSignal(InPin pin, EventArgs e)
    {
        Thread.CurrentThread.Join(200);
        if (pin.PinState == 1)
            setLightOn();
        else
            setLightOff();
    }
    public void setThreadSafeImage(Image iS)
    {
        string strUri2 = String.Format(@"pack://application:,,,/;component/Images/Signal_Gron_16.png");
        BitmapImage img = new BitmapImage(new Uri(strUri2));
        img.Freeze();

        iS.Dispatcher.BeginInvoke(
                    DispatcherPriority.Background,
                        new Action(() => iS.Source = img));

    }

2 Answers 2

1

You should have ObservableCollection<ImageSource> Images in your ViewModel. I think your UserControl with Image is unnecessary.

You must define ItemTemplate in ListBox:

<ListBox ItemsSource="{Binding Path=Images}" Width="400" Height="25" Margin="0,0,0,0" VerticalAlignment="Top" HorizontalAlignment="Left">
    <ListBox.ItemsPanel>
        <ItemsPanelTemplate>
            <WrapPanel IsItemsHost="True"/>
        </ItemsPanelTemplate>
    </ListBox.ItemsPanel>
    <ListBox.ItemTemplate>
        <DataTemplate>
            <Image Height="16" HorizontalAlignment="Left" Margin="0,0,0,0" Stretch="Fill" VerticalAlignment="Top" Width="16" Source="{Binding}" />
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

And how to fill collection Images? It's very easy. Add BitmapImage instances in loop like:

BitmapImage bi = new BitmapImage();
bi.BeginInit();
bi.UriSource = new Uri(@"/Images/image_file.png", UriKind.RelativeOrAbsolute);
bi.EndInit();
Sign up to request clarification or add additional context in comments.

3 Comments

Hello, I changed it do its now ObservableCollection<ImageSource> instead, but nothing shows up on in the listbox.. I edit my code to show how I add!
No idea :(. Look into Output window in visual studio or try change DispatcherPriority.DataBind.
You can't use signalImage. It's not correct.... Your collection (ItemsSource) is observablecollection<ImageSource> Images. If you want to change the image, you must have to change ... some item in observablecollection.
1

Well actually in your case (if your control stays that simple), you don't need a CustomControl, btw your example is IMHO called UserControl, anyways.

You can simply declare a DataTemplate. E.g.

<ListBox ItemsSource="{Binding YourCollectionInDataContext}"...>
    <ListBox.ItemTemplate>
        <DataTemplate>
            <StackPanel Orientation="Horizontal">
                <Image Source="{Binding SomePropertyOfYourItemVm1}"/>
                <TextBlock Text="{Binding SomePropertyOfYourItemVm2}"/>
            </StackPanel>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

For more information please refer here.

UserControls (composition of controls) and CustomControls (extend an existing control) should only be used, if there is no other possibility to implement the desired feature. This is a good articel about both types of controls.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.