简体   繁体   English

我如何从除主要的 class 访问 XAML object?

[英]how do I access a XAML object from a class other than main?

If I try "var mainpage new Mainpage()" I will run the mainpage constructor and then all the fields in the XAML object will return to null.如果我尝试“var mainpage new Mainpage()”,我将运行主页构造函数,然后 XAML object 中的所有字段将返回到 null。 How to I access XAML objects in silverlight that are from a different class but part of the same namespace?如何访问 silverlight 中来自不同 class 但属于同一命名空间的 XAML 对象?

Let me explain by example.让我举例说明。 If you look at the first answer, here is what I am encountering如果您查看第一个答案,这就是我遇到的

public class MyPage
{
    MyPage()
    {

      // the constructor makes all the variables from the xaml null
    }

    public TextBox MyTextBox
    {
        get { return SomeTextBox; }
    }
}


public class SomeOtherClass
{
    private void SomeFunction()
    {
        var page = new MyPage();   // this makes the text empty
        var sometext = page.MyTextBox.Text;   // so sometext will be empty
    }
}

So whatever the user imputs when the program first runs turns to null when I run SomeFunction.因此,当我运行 SomeFunction 时,无论用户在程序首次运行时输入的内容都会变成 null。

What I am first going to try is to see if when SomeClass is created, the values are put into that class.我首先要尝试的是查看是否在创建 SomeClass 时将值放入该 class 中。

If that fails, I am going to try MVVM.如果失败,我将尝试 MVVM。 I have seen the http://www.vimeo.com/8915487 video and I got the sample mvvm code我看过http://www.vimeo.com/8915487视频,我得到了示例 mvvm 代码

Here is the Model:这是 Model:

namespace SimpleMVVM.Model
{
    public class SimpleModel
    { 
        // super easy version
        //public string SomeSimpleValue { get; set; }

        private string _SomeSimpleValue = string.Empty;

        // actually do something version...
        public string SomeSimpleValue
        {
            get
            {
                return "some value";
            }
            set
            {
                _SomeSimpleValue = value;
            }
        }
    }
}

here is the view:这是视图:

and here is the viewmodel.cs这是viewmodel.cs

using Simple;
using SimpleMVVM.Model;

namespace SimpleMVVM.ViewModel
{
    public class SimpleViewModel : SimpleViewModelBase
    {
        private SimpleModel MyModel = new SimpleModel(); 

        public string SomeSimpleValue
        {
            get { return MyModel.SomeSimpleValue; }
            set
            {
                if (MyModel.SomeSimpleValue != value)
                {
                    MyModel.SomeSimpleValue = value;
                    RaisePropertyChanged("SomeSimpleValue");
                }
            }
        } 
    }
}

Using this example, I am wondering if it will just as easy as injecting a ViewModel and then changing the bindings in the Model and the View.使用这个例子,我想知道它是否像注入 ViewModel 然后更改 Model 和 View 中的绑定一样简单。

Is MVVM really this easy? MVVM 真的这么简单吗?

There is one more.还有一个。 It is the viewmodel base class它是viewmodel基础class

using System.ComponentModel;

namespace Simple
{
    public class SimpleViewModelBase : INotifyPropertyChanged
    { 
        public event PropertyChangedEventHandler PropertyChanged;

        public void RaisePropertyChanged(string PropertyName)
        {
            var e = new PropertyChangedEventArgs(PropertyName);
            PropertyChangedEventHandler changed = PropertyChanged;
            if (changed != null) changed(this, e);
        }
    }
}

OK, so now the hard part.好的,现在是困难的部分。 If I create a new class.如果我创建一个新的 class。 How do I get the data from the viewmodel class?如何从视图模型 class 获取数据?

First, let me get this rant out of the way: what you propose is very bad design.首先,让我摆脱这种咆哮:您提出的设计非常糟糕。 It fits the definition of smelly code .它符合臭代码的定义。

If you insist on doing it this way, the "best" approach to take is to declare some public variables on your page that return the actual UI elements.如果您坚持这样做,“最佳”方法是在您的页面上声明一些返回实际 UI 元素的公共变量。

<UserControl x:Class="MyNamespace.MyPage"  ...>
    <Grid>
        <TextBox x:Name="SomeTextBox" Width="100" />
    </Grid>
</UserControl>


public class MyPage
{
    public TextBox MyTextBox
    {
        get { return SomeTextBox; }
    }
}


public class SomeOtherClass
{
    private void SomeFunction()
    {
        var page = new MyPage();
        page.MyTextBox.Text = "some text";
    }
}

Of course the preferred method would be to use something like the MVVM pattern to implement binding from your window to its viewmodel, then you can just read the property values from the viewmodel, this way you avoid trying to touch any UI elements from a totally different class.当然首选的方法是使用类似 MVVM 模式的东西来实现从 window 到它的视图模型的绑定,然后你可以从视图模型中读取属性值,这样你就可以避免尝试从完全不同的地方触摸任何 UI 元素class。

Another way to do it (without going the full MVVM route) is to inject the necessary values into the constructor of the control/page that you are instantiating, and from there you can assign them to the appropriate UI element properties.另一种方法(不走完整的 MVVM 路线)是将必要的值注入到您正在实例化的控件/页面的构造函数中,然后您可以从那里将它们分配给适当的 UI 元素属性。 This is still smelly, but better than directly accessing the UI elements from the outside.这仍然很臭,但比直接从外部访问 UI 元素要好。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM