【发布时间】:2016-06-10 17:45:22
【问题描述】:
我有一个 line 类型的 observablecollection(observable collections 自动实现 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>
【问题讨论】:
-
你如何'连接到一个命令'?如果您已验证调用了
AddLine,我猜您将命令绑定到视图模型的不同实例。 -
@CharlesMager 如果您可以看一下,我添加了该命令的代码。我确实创建了一个新实例,但我将它设置为原始实例。这是否只是创建副本而不是参考?
-
那段代码很好,我的意思是它是如何绑定到 UI 上的。您的 XAML 没有带有命令绑定的按钮或类似内容。
-
@CharlesMager 啊,我明白了。抱歉,我现在把它包括在内了。
-
对我来说一切都很好。我唯一想知道的是您的财产名称:Lines。我怕它会和别的东西发生冲突。我将它重命名为 MyLines 只是为了暂时进行调试,以确保安全并确保我看到了正确的“线条”。
标签: c# wpf line observablecollection inotifypropertychanged