Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/silverlight/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Silverlight 更新对象上的ObservableCollection属性已更改_Silverlight_Data Binding_Observablecollection_Inotifypropertychanged - Fatal编程技术网

Silverlight 更新对象上的ObservableCollection属性已更改

Silverlight 更新对象上的ObservableCollection属性已更改,silverlight,data-binding,observablecollection,inotifypropertychanged,Silverlight,Data Binding,Observablecollection,Inotifypropertychanged,希望有人能帮我解决这个问题。我正在创建一个用于编辑图像的Silverlight应用程序。用户有一个项目,其中包含包含元素的图层。元素是文本和图像元素 我有一个代表这个项目的类。它包含一个ObservableCollection,每个层都有一个ObservableCollection。元素是一个抽象类。有一个从元素继承的TextElement和ImageElement类 我的问题是,当我更改集合中的元素时,UI永远不会更新。我在我的所有属性上使用INotifyPropertyChanged,并在集

希望有人能帮我解决这个问题。我正在创建一个用于编辑图像的Silverlight应用程序。用户有一个项目,其中包含包含元素的图层。元素是文本和图像元素

我有一个代表这个项目的类。它包含一个ObservableCollection,每个层都有一个ObservableCollection。元素是一个抽象类。有一个从元素继承的TextElement和ImageElement类

我的问题是,当我更改集合中的元素时,UI永远不会更新。我在我的所有属性上使用INotifyPropertyChanged,并在集合上捕获CollectionChanged,但仍然没有成功。ObservableCollection的CollectionChanged事件在其一个元素的更新中从未被命中

这是我最初拥有的代码:

void Elements_CollectionChanged(
    object sender,     
    System.Collections.Specialized.NotifyCollectionChangedEventArgs e) 
{ this.NotifyChange("Elements"); }
这是绑定:

<!-- Workspace -->
        <ScrollViewer Grid.Column="1" VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto" Margin="5" DataContext="{Binding Project}">
            <Canvas x:Name="Canvas" Background="LightGray" Width="{Binding Path=CanvasWidth}" Height="{Binding Path=CanvasHeight}">
                <ItemsControl ItemsSource="{Binding Path=Layers, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}">
                    <ItemsControl.ItemsPanel>
                        <ItemsPanelTemplate>
                            <Canvas />
                        </ItemsPanelTemplate>
                    </ItemsControl.ItemsPanel>
                    <ItemsControl.ItemTemplate>

                        <DataTemplate>                                
                            <ItemsControl ItemsSource="{Binding Path=Elements, Mode=OneWay}">
                                <ItemsControl.ItemsPanel>
                                    <ItemsPanelTemplate>
                                        <Canvas Background="{Binding Path=BackgroundColor}"
                                                Visibility="{Binding Path=Visible, Converter={StaticResource BoolConverter}}"
                                                Opacity="{Binding Path=Opacity}"
                                                Width="{Binding ElementName=Canvas, Path=DataContext.CanvasWidth}" 
                                                Height="{Binding ElementName=Canvas, Path=DataContext.CanvasHeight}">
                                        </Canvas>
                                    </ItemsPanelTemplate>
                                </ItemsControl.ItemsPanel>
                                <ItemsControl.ItemTemplate>
                                    <DataTemplate>
                                        <Canvas>
                                            <ContentControl Content="{Binding Converter={StaticResource ElementConverter}}"
                                                            Canvas.Top="{Binding Path=Top, Mode=TwoWay}"
                                                            Canvas.Left="{Binding Path=Left, Mode=TwoWay}"
                                                            Opacity="{Binding Path=Opacity}"
                                                            MouseLeftButtonDown="ContentControl_MouseLeftButtonDown">
                                                <interactivity:Interaction.Behaviors>
                                                    <behaviors:DragInCanvasBehavior />
                                                </interactivity:Interaction.Behaviors>
                                            </ContentControl>
                                        </Canvas>
                                    </DataTemplate>
                                </ItemsControl.ItemTemplate>
                            </ItemsControl>                                
                        </DataTemplate>

                    </ItemsControl.ItemTemplate>
                </ItemsControl>
            </Canvas>
        </ScrollViewer>
这是包含到集合的类:

public class Layer : BaseBLL
{
    private int numberOfElements;

    #region Properties
    public int Order
    {
        get { return this.GetValue<int>("Order"); }
        set { this.SetValue<int>("Order", value); }
    }

    public string BackgroundColor
    {
        get { return this.GetValue<string>("BackgroundColor"); }
        set { this.SetValue<string>("BackgroundColor", value); }
    }

    public double Opacity
    {
        get { return this.GetValue<double>("Opacity"); }
        set { this.SetValue<double>("Opacity", value); }
    }

    public bool Visible
    {
        get { return this.GetValue<bool>("Visible"); }
        set { this.SetValue<bool>("Visible", value); }
    }

    public ObservableCollection<Element> Elements { get; set; }

    public Element SelectedElement
    {
        get { return this.GetValue<Element>("SelectedElement"); }
        set { this.SetValue<Element>("SelectedElement", value); }
    }
    #endregion

    #region Commands
    public ICommand AddTextElementCommand { get; set; }
    public ICommand AddImageElementCommand { get; set; }
    public ICommand DeleteElementCommand { get; set; }
    public ICommand SetSelectedElementCommand { get; set; }
    #endregion

    #region Methods
    public Layer()
        :this("Untitled", 0, "#ffffff", 1, true, new ObservableCollection<Element>())
    {
    } 

    public Layer(string name, int order, string backgroundColor, double opacity, bool visible, ObservableCollection<Element> elements)
        : base(name)
    {
        this.Order = order;
        this.BackgroundColor = backgroundColor;
        this.Opacity = opacity;
        this.Visible = visible;
        this.Elements = elements;

        this.Elements.CollectionChanged += new System.Collections.Specialized.NotifyCollectionChangedEventHandler(Elements_CollectionChanged);

        this.AddTextElementCommand = new DelegateCommand(AddTextElement, CanAddTextElement);
        this.AddImageElementCommand = new DelegateCommand(AddImageElement, CanAddImageElement);
        this.DeleteElementCommand = new DelegateCommand(DeleteElement, CanDeleteElement);
    }

    private void Elements_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
    {
        foreach (Element element in e.NewItems)
            element.PropertyChanged += new System.ComponentModel.PropertyChangedEventHandler(element_PropertyChanged);
    }

    void element_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
    {
        this.NotifyChange("Elements");
    }

    private bool CanAddTextElement(object param) { return true; }
    private void AddTextElement(object param)
    {
        TextElement text = new TextElement();
        text.Order = this.numberOfElements;
        this.Elements.Add(text);

        numberOfElements++;
        this.SelectedElement = text;
    }       

    private bool CanAddImageElement(object param) { return true; }
    private void AddImageElement(object param)
    {
        var dialog = new OpenFileDialog()
        {
            Filter = "Image Files (*.bmp;*.jpg;*.gif;*.png;)|*.bmp;*.jpg;*.gif;*.png;",
            Multiselect = false
        };

        bool? userClickedOK = dialog.ShowDialog();
        if (userClickedOK == true)
        {
            string fileName = dialog.File.Name;
            FileStream stream = dialog.File.OpenRead();

            var imageSource = new BitmapImage();
            using (FileStream fileStream = stream)
            {
                imageSource.SetSource(fileStream);
                byte[] data = new byte[fileStream.Length];
                fileStream.Read(data, 0, data.Length);
                fileStream.Flush();
                fileStream.Close();
            }

            ImageElement img = new ImageElement();
            img.Name = fileName;
            img.Order = this.numberOfElements;
            img.Source = imageSource;
            img.Height = imageSource.PixelHeight;
            img.Width = imageSource.PixelWidth;
            this.Elements.Add(img);

            this.numberOfElements++;
            this.SelectedElement = img;
        }
    }

    private bool CanDeleteElement(object param)
    {
        if (this.SelectedElement != null)
            return true;
        else
            return false;
    }

    private void DeleteElement(object param)
    {
        throw new NotImplementedException();
    }      
    #endregion
}
这是其中一个元素的代码:

public class TextElement : Element
{
    public string Text
    {
        get { return this.GetValue<string>("Text"); }
        set { this.SetValue<string>("Text", value); }
    }

    public int FontSize
    {
        get { return this.GetValue<int>("FontSize"); }
        set { this.SetValue<int>("FontSize", value); }
    }

    public bool Bold
    {
        get { return this.GetValue<bool>("Bold"); }
        set { this.SetValue<bool>("Bold", value); }
    }

    public bool Italic
    {
        get { return this.GetValue<bool>("Italic"); }
        set { this.SetValue<bool>("Italic", value); }
    }

    public string Color
    {
        get { return this.GetValue<string>("Color"); }
        set { this.SetValue<string>("Color", value); }
    }

    public FontFamily Font
    {
        get { return this.GetValue<FontFamily>("Font"); }
        set { this.SetValue<FontFamily>("Font", value); }
    }

    public TextElement()
        : this("Untitled", 1, 5, 5, 0, 0, 0, "New text", 12, false, false, "#aaaaaa", new FontFamily("Arial"))
    {
    }

    public TextElement(string name, double opacity, double top, double left, double rotateAngle, double centerX, double centerY, 
        string text, int fontSize, bool bold, bool italic, string color, FontFamily font)
        : base(name, opacity, top, left, rotateAngle, centerX, centerY)
    {
        this.Text = text;
        this.FontSize = fontSize;
        this.Bold = bold;
        this.Italic = italic;
        this.Color = color;
        this.Font = font;
    }
}

如果有人能帮助我,我将不胜感激。

您是否从SetValue内部触发PropertyChanged事件? 否则,应该为元素的每个属性执行此操作

public string Text
    {
        get { return this.GetValue<string>("Text"); }
        set { this.SetValue<string>("Text", value); this.InvokePropertyChanged("Text"); }
    }

private void InvokePropertyChanged( string propertyName )
{
  if( this.PropertyChanged != null )
    this.PropertyChanged( this, new PropertyChangedEventArgs( propertyName ) );
}

但是您是否将elements集合绑定到UI中的控件?如果是的话,你能邮寄你的装订吗?另外,您可以发布元素代码吗?元素是否实现INotifyPropertyChanged?是的,我的所有对象都实现INotifyPropertyChanged
public string Text
    {
        get { return this.GetValue<string>("Text"); }
        set { this.SetValue<string>("Text", value); this.InvokePropertyChanged("Text"); }
    }

private void InvokePropertyChanged( string propertyName )
{
  if( this.PropertyChanged != null )
    this.PropertyChanged( this, new PropertyChangedEventArgs( propertyName ) );
}