我有一个类型行的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>
答案 0 :(得分:3)
问题是实例问题。您的Window
创建了MapViewModel
的新实例,而您的UserControl
创建了MapViewModel
的新实例。
单击该按钮时,会在Lines
创建的实例上的Window
中添加一行。这不是您的UserControl
绑定的实例。
更改此方法的最简单方法可能是将DataContext
的{{1}}设置为MapView
中的MapViewModel
:
Window
从<local:MapView DataContext="{StaticResource MapVM}" />
移除资源和绑定的创建,UserControl
只会从其父级继承ItemsControl
。
DataContext