我在我的Siverlight项目中使用了Galasoft的Light MVVM。
我已经按照指示设置好了一切:ViewModel绑定到了View的DataContext;
我在View中有一个名为inkCanvas的画布。
当ViewModel获得更新后的项目数据时,我需要引用inkCanvas来创建一个CanvasRender实例public CanvasRender(Canvas canvas, ProjectData pdata)。
问题出在MVVM中,ViewModel对View一无所知,那么我如何在View中引用控件(inkCanvas
附言(编辑):我的变通方法是:当我将项目数据传递给ViewModel时,我也传递了View的代码隐藏中的inkCanvas。
发布于 2012-09-26 02:28:54
根据上面的注释,一种方法是扩展Canvas,并将对CanvasRender的引用保留在该类中。
public class MyCanvas : Canvas
{
private CanvasRender _canvasRender;
private ProjectData _data;
public ProjectData Data
{
get { return _data; }
set
{
_data = value;
_canvasRender = new CanvasRender(this, _data);
}
}
public MyCanvas() : base()
{
}
}您可能还想让ProjectData成为一个依赖属性,以便它是可绑定的。
这允许您维护MVVM模式,因为现在您可以用XAML编写:
<local:MyCanvas ProjectData="{Binding ViewModel.ProjectData}" />发布于 2012-09-25 03:40:21
在MVVM模式中,您不会在ViewModel中直接引用控件。在MVVM中,一切都是“绑定”的。您的inkCanvas将绑定到您的ViewModel中的属性。
public class MyViewModel : INotifyPropertyChanged
{
private readonly StrokeCollection _mystrokes;
public MyViewModel ()
{
_mystrokes= new StrokeCollection();
(_mystrokesas INotifyCollectionChanged).CollectionChanged += delegate
{
//the strokes have changed
};
}
public event PropertyChangedEventHandler PropertyChanged;
public StrokeCollection MyStrokes
{
get
{
return _mystrokes;
}
}
private void OnPropertyChanged(string propertyName)
{
var handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}和XAML:
<InkCanvas Strokes="{Binding MyStrokes}"/>编辑:
也许您的解决方案是使用EventToCommand :这允许将UI事件直接绑定到XAML中的ICommand (并使用Args将引用传递给inkCancas)
<i:Interaction.Triggers>
<i:EventTrigger EventName="Loaded">
<cmd:EventToCommand Command="{Binding Mode=OneWay, Path=LoadedCommand}"
PassEventArgsToCommand="True" />
</i:EventTrigger>
</i:Interaction.Triggers>发布于 2012-09-26 13:58:44
如果要使用EventToCommand方法(您在另一个答案中尝试过),那么不要使用PassEventArgsToCommand属性,而是使用CommandParameter属性并将其绑定到画布。
<i:Interaction.Triggers>
<i:EventTrigger EventName="Loaded">
<cmd:EventToCommand Command="{Binding Path=CanvasLoadedCommand}"
CommandParameter="{Binding ElementName=inkCanvas}" />
</i:EventTrigger>
</i:Interaction.Triggers>然后在你的ViewModel中:
public class ViewModel
{
private Canvas m_canvas;
public RelayCommand<Canvas> CanvasLoadedCommand { get; private set; }
public ViewModel()
{
CanvasLoadedCommand = new RelayCommand<Canvas>(canvas =>
{
m_canvas = canvas;
});
}
}因此,一旦加载了画布,就应该在视图模型中保存对它的引用。
https://stackoverflow.com/questions/12571529
复制相似问题