首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何解决引用视图控件的问题

如何解决引用视图控件的问题
EN

Stack Overflow用户
提问于 2012-09-25 03:27:07
回答 3查看 160关注 0票数 2

我在我的Siverlight项目中使用了Galasoft的Light MVVM。

我已经按照指示设置好了一切:ViewModel绑定到了ViewDataContext

我在View中有一个名为inkCanvas的画布。

ViewModel获得更新后的项目数据时,我需要引用inkCanvas来创建一个CanvasRender实例public CanvasRender(Canvas canvas, ProjectData pdata)

问题出在MVVM中,ViewModelView一无所知,那么我如何在View中引用控件(inkCanvas

附言(编辑):我的变通方法是:当我将项目数据传递给ViewModel时,我也传递了View的代码隐藏中的inkCanvas

EN

回答 3

Stack Overflow用户

发布于 2012-09-26 02:28:54

根据上面的注释,一种方法是扩展Canvas,并将对CanvasRender的引用保留在该类中。

代码语言:javascript
复制
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编写:

代码语言:javascript
复制
<local:MyCanvas ProjectData="{Binding ViewModel.ProjectData}" />
票数 1
EN

Stack Overflow用户

发布于 2012-09-25 03:40:21

在MVVM模式中,您不会在ViewModel中直接引用控件。在MVVM中,一切都是“绑定”的。您的inkCanvas将绑定到您的ViewModel中的属性。

代码语言:javascript
复制
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:

代码语言:javascript
复制
<InkCanvas Strokes="{Binding MyStrokes}"/>

编辑:

也许您的解决方案是使用EventToCommand :这允许将UI事件直接绑定到XAML中的ICommand (并使用Args将引用传递给inkCancas)

代码语言:javascript
复制
<i:Interaction.Triggers>
    <i:EventTrigger EventName="Loaded">
        <cmd:EventToCommand Command="{Binding Mode=OneWay, Path=LoadedCommand}"
                            PassEventArgsToCommand="True" />
    </i:EventTrigger>
</i:Interaction.Triggers>
票数 0
EN

Stack Overflow用户

发布于 2012-09-26 13:58:44

如果要使用EventToCommand方法(您在另一个答案中尝试过),那么不要使用PassEventArgsToCommand属性,而是使用CommandParameter属性并将其绑定到画布。

代码语言:javascript
复制
<i:Interaction.Triggers>
    <i:EventTrigger EventName="Loaded">
        <cmd:EventToCommand Command="{Binding Path=CanvasLoadedCommand}"
                            CommandParameter="{Binding ElementName=inkCanvas}" />
    </i:EventTrigger>
</i:Interaction.Triggers>

然后在你的ViewModel中:

代码语言:javascript
复制
public class ViewModel
{
    private Canvas m_canvas;

    public RelayCommand<Canvas> CanvasLoadedCommand { get; private set; }

    public ViewModel() 
    { 
        CanvasLoadedCommand = new RelayCommand<Canvas>(canvas =>  
        { 
            m_canvas = canvas;
        }); 
    }
}

因此,一旦加载了画布,就应该在视图模型中保存对它的引用。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12571529

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档