我想要一个列表框,它会在我的Canvas中以silverlight显示所有图像和文本“图层”。当我尝试查看列表框或当我在添加元素时查看列表框时,我当前崩溃的代码。我无法弄清楚为什么。有人能指出我正确的方向吗?
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>
Project.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;
}
}
答案 0 :(得分:1)
可能有一个原因,因为您使用Grid元素中的Path属性进行绑定。
您应该使用绑定源,并将Project对象设置为静态资源,您可以在调用绑定源时指向该资源。
像这样:
<Window
xlmns:local="NamespaceOfMyProject">
<Window.Resources>
<local:Project x:key="MyProjectResource" />
</Window.Resources>
<Grid DataContext="{Binding Source={StaticResource MyProjectResource}}>
....
</Grid>
....
</Window>
原因是:指向对象时使用“Source”,指向属性时使用“Path”。
设置DataContext的另一种方法是使用此C#代码在代码隐藏中执行此操作。但首先给你的网格命名,所以它可以在代码隐藏中引用:
<Grid x:Name="myGrid">
Codebehind:
myGrid.DataContext = new Project();
答案 1 :(得分:0)
错误地处理图像通常会导致崩溃;显示元素实现的代码以及设置图像的方式。
此外,您的XAML缺少ItemTemplate,您可以在其中设置图像和文本。
答案 2 :(得分:0)
我猜它会崩溃因为你已经添加了Canvas的FrameworkElements,但是你也将它们添加到你的List中。 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");
}