ObservableCollection <line>不在UI上更新

时间:2016-06-10 17:45:23

标签: c# wpf line observablecollection inotifypropertychanged

我有一个类型行的observablecollection(可观察集合自动实现INotifyPropertyChanged接口)和一个为其添加一行名为CreateLine的函数。如果我在构造函数中调用CreateLine,它将出现。但是如果我尝试(通过连接到命令)之后再尝试它,它将不会更新UI。有什么想法吗?

代码:

namespace MovementMap.ViewModels
{
    class MapViewModel : INotifyPropertyChanged
    {
        public AddLineCommand addlinecommand { get; set; }

        public MapViewModel()
        {
            //test
            CreateLine(100, 100, 150, 150);
            CreateLine(150, 150, 200, 280);

            addlinecommand = new AddLineCommand(this);
        }
        private ObservableCollection<Line> lines = new ObservableCollection<Line>();
        public ObservableCollection<Line> Lines
        {
            get
            {
                return lines;
            }
        }
        public void CreateLine(int x1, int y1, int x2, int y2)
        {
            Line line = new Line();
            line.X1 = x1;
            line.Y1 = y1;
            line.X2 = x2;
            line.Y2 = y2;

            line.StrokeThickness = 2;

            SolidColorBrush black = new SolidColorBrush();
            black.Color = Colors.Black;

            line.Stroke = black;

            Lines.Add(line);
            OnPropertyChanged("Lines");
        }
        public void AddLine()
        {
            //doesnt seem to be updating ui.
            CreateLine(0, 0, 100, 100);
        }
        #region INotifyPropertyChanged
        public event PropertyChangedEventHandler PropertyChanged;
        private void OnPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
        #endregion
    }
}

XAML:

<UserControl x:Class="MovementMap.MapView"
             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" 
             xmlns:viewmodel="clr-namespace:MovementMap.ViewModels"
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300">
    <UserControl.Resources>
        <viewmodel:MapViewModel x:Key="MapVM"/>
    </UserControl.Resources>
    <Grid x:Name="LayoutRoot" DataContext="{Binding Mode=OneWay, Source={StaticResource MapVM}}">
        <ItemsControl x:Name="Items" ItemsSource="{Binding Lines, Source={StaticResource MapVM}, UpdateSourceTrigger=PropertyChanged}">
            <ItemsControl.ItemsPanel>
                <ItemsPanelTemplate>
                    <Canvas/>
                </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>
        </ItemsControl>
        <!--<Line X1="0" X2="100" Y1="0" Y2="100" Stroke="Red" StrokeThickness="4"/>-->
    </Grid>
</UserControl>

命令:

namespace MovementMap.ViewModels.Commands
{
    class AddLineCommand : ICommand
    {
        private MapViewModel ViewModel;
        public AddLineCommand(MapViewModel VM)
        {
            ViewModel = VM;
        }


        public bool CanExecute(object parameter)
        {
            return true;
        }

        public event EventHandler CanExecuteChanged
        {
            add { CommandManager.RequerySuggested += value; }
            remove { CommandManager.RequerySuggested -= value; }
        }
        public void Execute(object parameter)
        {
            this.ViewModel.AddLine();
        }
    }
}

按钮XAML:

<Window
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:MovementMap" x:Class="MovementMap.MainWindow"
        xmlns:viewmodel="clr-namespace:MovementMap.ViewModels"
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <viewmodel:MapViewModel x:Key="MapVM"/>
    </Window.Resources>
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*"/>
            <ColumnDefinition Width="100"/>
        </Grid.ColumnDefinitions>
        <local:MapView/>
        <Button Grid.Column="1" Content="Add Line" Height="20" Command="{Binding addlinecommand, Source={StaticResource MapVM}}"/>
    </Grid>
</Window>

1 个答案:

答案 0 :(得分:3)

问题是实例问题。您的Window创建了MapViewModel的新实例,而您的UserControl创建了MapViewModel的新实例。

单击该按钮时,会在Lines 创建的实例上的Window 中添加一行。这不是您的UserControl绑定的实例。

更改此方法的最简单方法可能是将DataContext的{​​{1}}设置为MapView中的MapViewModel

Window

<local:MapView DataContext="{StaticResource MapVM}" /> 移除资源和绑定的创建,UserControl只会从其父级继承ItemsControl

DataContext