0

我想要一个列表框,它可以在 Silverlight 中显示我在 Canvas 上的所有图像和文本“图层”。当我尝试查看列表框或添加元素时查看列表框时,我当前的代码崩溃了。我不知道为什么。有人可以指出我正确的方向吗?

XML -

                            <Grid DataContext="{Binding Path=Project}">
                                ...
                                ...
                                <TextBlock Name="textBlock1" Text="Layers" Margin="18,16,0,0" />

                                <StackPanel Grid.Row="1" Grid.RowSpan="2" Grid.ColumnSpan="2">
                                    <ListBox ItemsSource="{Binding Path=Elements}" Height="175" Name="listBox1" Width="172"/>
                                </StackPanel>

                            </Grid>

项目.cs

        //List of elements
    private ObservableCollection<FrameworkElement> elements;
    public ObservableCollection<FrameworkElement> Elements
    {
        get { return elements; }
        set
        {
            elements = value;
            NotifyPropertyChanged("Elements");
        }
    }
// An example of how an element is added to the Elements collection
// There are also image elements added similarly
private void AddTextElement(object param)
    {
        TextBlock textBlock = new TextBlock();
        textBlock.Text = "New Text";
        textBlock.Foreground = new SolidColorBrush(Colors.Gray);
        textBlock.FontSize = 25;
        textBlock.FontFamily = new FontFamily("Arial");
        textBlock.Cursor = Cursors.Hand;
        textBlock.Tag = null;


        this.Elements.Add(textBlock);
        numberOfElements++;


        this.SelectedElement = textBlock;
        this.selectedTextElement = textBlock;
    }

private void AddImageElement(object param)
    {
        bool? gotImage;
        string fileName;
        BitmapImage imageSource = GetImageFromLocalMachine(out gotImage, out fileName);


        if (gotImage == true)
        {
            Image image = new Image();
            OrderElements(image);
            image.Name = fileName;
            image.Source = imageSource;
            image.Height = imageSource.PixelHeight;
            image.Width = imageSource.PixelWidth;
            image.MaxHeight = imageSource.PixelHeight;
            image.MaxWidth = imageSource.PixelWidth;
            image.Cursor = Cursors.Hand;
            image.Tag = null;


            AddDraggingBehavior(image);
            image.MouseLeftButtonUp += element_MouseLeftButtonUp;

            this.Elements.Add(image);
            numberOfElements++;

            this.SelectedElement = image;
            this.SelectedImageElement = image;

        }
    }
4

3 回答 3

1

一个原因可能是因为您在 Grid 元素中使用 Path 属性进行绑定。

您应该使用绑定源,并将您的项目对象设置为静态资源,您可以在调用绑定源时指向它。

像这样:

<Window
    xlmns:local="NamespaceOfMyProject">

    <Window.Resources>
        <local:Project x:key="MyProjectResource" />
    </Window.Resources>

    <Grid DataContext="{Binding Source={StaticResource MyProjectResource}}>
    ....
    </Grid>
    ....
</Window>

原因是:指向对象时使用“源”,指向属性时使用“路径”。

设置 DataContext 的另一种方法是使用此 C# 代码在代码隐藏中进行。但首先给您的网格命名,以便在代码隐藏中引用它:

<Grid x:Name="myGrid">

代码隐藏:

myGrid.DataContext = new Project();
于 2012-09-26T16:08:05.407 回答
0

错误地使用图像通常会导致崩溃;显示实现元素的代码以及如何设置图像。

此外,您的 XAML 缺少 ItemTemplate,您将在其中设置图像和文本。

于 2012-09-27T14:35:22.730 回答
0

我猜它崩溃了,因为您已经将 FrameworkElements 添加到 Canvas 中,但随后您还将它们添加到列表中。FrameworkElements 通常不喜欢被多次添加到可视化树中。

如果这是问题所在,这样的事情可能会解决它(将您的列表绑定到ElementsAsStrings):

    private ObservableCollection<FrameworkElement> elements;
    public ObservableCollection<FrameworkElement> Elements
    {
        get { return elements; }
        set
        {
            if(elements != null)
                elements.CollectionChanged -= onElementsChanged;
            elements = value;
            if(elements != null)
                elements.CollectionChanged += onElementsChanged;

            NotifyPropertyChanged("Elements");
            NotifyPropertyChanged("ElementsAsStrings");
        }
    }

    public IEnumerable<string> ElementsAsStrings
    {
        get
        {
            foreach(var element in Elements)
            {
                if(element is TextBox)
                    yield return (element as TextBox).Text;
                // More cases here
            }
        }
    }

    private void onElementsChanged(object sender, NotifyCollectionChangedEventArgs e)
    {
        NotifyPropertyChanged("ElementsAsStrings");
    }
于 2012-09-28T01:27:56.120 回答