将带图像的自定义控件添加到wpf Listbox

时间:2013-05-24 11:24:35

标签: c# wpf xaml events

我有这个项目,我希望通过将一个自定义控件(inSignalLight)添加到列表框(或其他一些控件,我想将它们排成一行)来将一些图像设置到我的屏幕上。我已将图像设置在自定义控件中并将它们添加到" ObservableCollection",但没有显示任何内容。我是WPF的新手,所以不太确定xaml是否正确...如果有更好的方法,那么在列表框中,请告诉我。

inSignalLights = new ObservableCollection<inSignalLight>();

这是页面中我想要显示图片的xaml。

<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>

编辑:

这是自定义控件的xaml

<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>

编辑:

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 个答案:

答案 0 :(得分:1)

您的ViewModel中应该有ObservableCollection<ImageSource> Images。 我认为你的UserControl with Image是不必要的。

您必须在ListBox中定义ItemTemplate:

<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>

如何填写收藏图片?这很容易。 像循环一样添加BitmapImage实例:

BitmapImage bi = new BitmapImage();
bi.BeginInit();
bi.UriSource = new Uri(@"/Images/image_file.png", UriKind.RelativeOrAbsolute);
bi.EndInit();

答案 1 :(得分:1)

实际上在您的情况下(如果您的控件保持这么简单),您不需要CustomControl,顺便说一句,您的示例是恕我直言,UserControl,无论如何。

您只需声明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>

有关详细信息,请参阅here

如果没有其他可能性来实现所需的功能,则只应使用

UserControls(控件组合)和CustomControls(扩展现有控件)。 This是关于这两种控件的良好清晰度。