如何将xaml(view)的当前实例(发送方)传递给ViewModel

时间:2011-03-16 09:24:40

标签: mvvm-light

我需要viewmodel中的view实例来操作ViewModel中的视图元素。如何将当前View(发件人)的实例传递给ViewModel。

<UserControl...>
    <br>...<br>
    <Button x:Name="btnRemove" Width="100" Height="30" 
        Content="Remove" Margin="5" Visibility="Hidden"  
        Command="{Binding CellFrame.WidgetRemoveCommand, Mode=OneWay, Source={StaticResource Locator}}" 
        CommandParameter="{Binding Mode=OneWay}" />
    <br>...<br>
</UserControl>

这会在WidgetRemoveCommand中传递viewModel的实例。如何传递Usercontrol的Intance。

由于

3 个答案:

答案 0 :(得分:1)

为了解决这个问题,当父视图创建子视图时,让它在创建时向视图模型中注入“remove”命令,如下所示。

//Parent
var model = new ChildControlViewModel();
var view  = new ChildControl(model);
Children.Add(view);
model.RemoveCommand = ()=>Children.Remove(view);

显然这是大大简化的,我也确保你有一个与视图模型绑定的视图控件工厂,即使在后面的代码中有这个似乎......对我来说也是错的。

此外,您可以使用信使并注册消息,这是一种可接受的方式来通知视图模型的操作视图。例如,我使用它来为我的一个项目中的缩放滑块注册view-&gt;视图交互。这种方法可以用于删除。

    public FlickrPhotoBrowserViewModel()
    {
        Photos = new ObservableCollection<FlickrPhotoViewModel>();
        Messenger.Default.Register<ZoomChangedMessage>(this, message => ImageSize = message.Content);
    }

创建照片时:

    public async Task CreatePhotoContainerAsync(string photoID, IImageSearchService searchService, IStreamService streamService)
    {
        if (photoID != null)
        {
            var Photo = new FlickrPhotoViewModel(photoID);

            Photo.ShowDetailsCommand = new RelayCommand(() =>
            {
                FlickrPhotoDataViewer.ShowPhoto(photoID, searchService, streamService);
            });



            // REMOVE CODE!!! ^_^
            Photo.RemovePhotoCommand= new RelayCommand(() =>
            {
                Photos.Remove(Photo);
                FlickrPhotoDataViewer.CleanupPhotoElement(Photo);
            });
            // REMOVE CODE!!! ^_^


            //update async collection from bound UI thread
            DispatcherHelper.CheckBeginInvokeOnUI(() => Photos.Add(Photo));

            var target = await searchService.GetPhotoThumbnailUriAsync(photoID);

            Photo.ImageStream = await streamService.GetStreamAsync(target);

            Debug.WriteLine("Image Download Complete " + target);
        }
        else
        {
            Debug.WriteLine("Image NULL " + photoID);
        }
    }

答案 1 :(得分:0)

例如,MVVM Light可以选择使用该命令传递EventArgs。在EventArgs中有发件人,并且从该发件人(父母等)可以搜索树。

但无论如何,在viewmodel中混淆视图并不是一个好主意。我会将逻辑放在View的代码中,这很好。

答案 2 :(得分:0)

在这种情况下,您只需在用户控件的构造函数中绑定Command属性即可。有一个定位器类,它保持指向CellFrame视图模型的指针。

btnRemove.Command = some_locator_class.static_method.WidgetRemoveCommand;
btnRemove.CommandParameter = this;

CellFrame视图模型可以有一个名为WidgetRemoveCommand的RelayCommand,如下所示:

RelayCommand<CellFrame> WidgetRemoveCommand 

现在,这个relay命令的委托方法定义如下:

public void WidgetRemoveAction(CellFrame cell)
{
    // here you get it! 
}

所以,诀窍是在命令参数中发送'this'。

希望这有帮助。