标签: viewmodel

如何在ViewModel中呈现(视图)模型的集合

我对C#/ WPF的MVVM设计有疑问.我看过几个演示应用程序,但它们并没有真正解决我的问题.我的应用程序由包含其他对象的对象组成.就像父子关系一样.

我现在的问题是:

  • children属性是否必须是ViewModel
  • 如果是这样,我如何通过ViewModels 创建包含现有 Child对象的新Parent对象?

我有以下情况:

class Child {
    string Name;
}

class ChildVM {
    Child _child;
    string Name{return _child.Name;}
}

class Parent {
    string Name;
    List<Child> children;
}

class ParentVM{
    Parent _parent;

    string Name{return _parent.Name;}
    List<ChildVM> children {get;set;}

    ParentVM(Parent p){_parent = p;}
}

void CreateANewParent(){
    List<ChildVM> children = new List<ChildVM>(){new ChildVM(new Child()),...};
    ParentVM parent = new ParentVM(new Parent());
    foreach(ChildVM child in children)
        parent.children.Add(child);
}
Run Code Online (Sandbox Code Playgroud)

这里的问题是,ParentVM包含ChildVM,但实际的Parent(在ParentVM内)没有ChildVM对象包含的Child对象.我也认为复制Child对象不是一个好主意,因为它会导致冗余,在我的应用程序上下文中也没有必要/可能创建新的Child对象.

我还考虑过以下课程设计:

class ParentVM {
    Parent _parent;

    string Name{return _parent.Name;}
    List<Child> children …
Run Code Online (Sandbox Code Playgroud)

collections wpf mvvm viewmodel

11
推荐指数
1
解决办法
3645
查看次数

在哪里创建参数化ViewModel?

我最近参数化了我的ViewModel的构造函数.在此之前,我在窗口中这样做:

<Window.DataContext>
    <vm:MyViewModel />
</Window.DataContext>
Run Code Online (Sandbox Code Playgroud)

该框架为我实例化了ViewModel.

我知道我可以在代码中设置DataContext,但我更喜欢XAML方式,因此设计人员可以在设计时显示我的测试数据.

这可能吗?

wpf mvvm viewmodel

11
推荐指数
2
解决办法
6565
查看次数

什么时候使用ViewData而不是ViewModels?

假设您想开发控制器以便使用ViewModel来包含您呈现的视图的数据,那么是否所有数据都包含在ViewModel中?什么条件可以绕过ViewModel?

我问的原因是我处在一些代码使用ViewData而一些代码正在使用ViewModel的位置.我想在团队中分发一套关于何时正确使用ViewData的指南,以及何时只是采用快捷方式.我希望得到其他开发人员的意见,以便我知道我的指导方针不仅仅是我的偏见.

asp.net-mvc viewdata viewmodel

11
推荐指数
1
解决办法
1176
查看次数

如何在Xamarin Forms中从ViewModel设置焦点

我想在做一些异步操作后将焦点设置在一个SearchBox控件中,我想我的ViewModel中做到这一点.

我怎么能这样做?

编辑

ViewModel代码:

    private bool _searchBarFocused;

    public bool SearchBarFocused
    {
        get { return _searchBarFocused; }
        set
        {
            _searchBarFocused = value;
            base.OnPropertyChanged("SearchBarFocused");
        }
    }

    public async Task InitializeData()
    {
        // Other operations...

        SearchBarFocused = true;
    }
Run Code Online (Sandbox Code Playgroud)

查看代码隐藏代码:

    protected override void OnAppearing()
    {
        base.OnAppearing();
        (this.BindingContext as MyViewModel).InitializeData();
    }
Run Code Online (Sandbox Code Playgroud)

SearchBar XAML代码:

  <SearchBar SearchCommand="{Binding SearchItemsCommand}">
    <SearchBar.Triggers>
      <DataTrigger TargetType="SearchBar"
                   Binding="{Binding SearchBarFocused, Mode=TwoWay}" Value="True">
        <Trigger.EnterActions>
          <triggers:SearchBarFocusTriggerAction Focused="True" />
        </Trigger.EnterActions>

        <Trigger.ExitActions>
          <triggers:SearchBarFocusTriggerAction Focused="False" />
        </Trigger.ExitActions>
      </DataTrigger>
    </SearchBar.Triggers>
  </SearchBar> …
Run Code Online (Sandbox Code Playgroud)

c# xaml focus viewmodel xamarin-forms

11
推荐指数
1
解决办法
7420
查看次数

Android架构组件ViewModel上下文

我正在研究谷歌的架构组件,以便将ViewModel和LiveData实现到我的应用程序,官方文档说:

注意:由于ViewModel比特定活动和片段实例更长,因此它永远不应引用View或任何可能包含对活动上下文的引用的类.如果ViewModel需要Application上下文(例如,查找系统服务),它可以扩展AndroidViewModel类并具有在构造函数中接收Application的构造函数(因为Application类扩展了Context)

在那之后,我最终得到了这样的代码:

public class ViewModelTest extends AndroidViewModel {

public ViewModelTest(Application application) {
    super(application);
}

public void test(){
    Prefs.getCurrentCode(getApplication());
}
Run Code Online (Sandbox Code Playgroud)

我应该在活动中正常实例吗?

  val viewModel2 = ViewModelProviders.of(this).get(ViewModelTest::class.java)
    viewModel2.test()
Run Code Online (Sandbox Code Playgroud)

不是很糟糕吗?要在需要访问SharedPreferences或需要上下文的任何内容时使用此应用程序变量?如果是,我应该避免在ViewModel上使用它并仅在视图上使用它吗?特别是如果我想用一个需要上下文的值更新UI组件.我有点不知道如何解决这个问题,我愿意接受任何建议.

提前致谢

android viewmodel android-context android-application-class android-livedata

11
推荐指数
1
解决办法
7291
查看次数

Android ViewModel调用Activity方法

我正在我的项目中使用android AAC库和Android数据绑定库.我有AuthActivity和AuthViewModel扩展了android的ViewModel类.在某些情况下,我需要让Activity为ViewModel调用一些方法.例如,当用户点击Google Auth或Facebook Auth按钮时,它在Activity类中初始化(因为初始化GoogleApiClient我需要Activity上下文,我无法传递给ViewModel,视图模型无法存储Activity字段).在Activity类中实现了Google Api和Facebook API的所有逻辑:

//google api initialization
googleApiClient = new GoogleApiClient.Builder(this)
                .enableAutoManage(this, this)
                .addApi(Auth.GOOGLE_SIGN_IN_API, gso)
                .build();

//facebook login button
loginButton.setReadPermissions(Arrays.asList("email", "public_profile"));
loginButton.registerCallback(callbackManager,
Run Code Online (Sandbox Code Playgroud)

此外,我需要调用登录意图,这也需要活动上下文:

Intent signInIntent = Auth.GoogleSignInApi.getSignInIntent(googleApiClient);
startActivityForResult(signInIntent, GOOGLE_AUTH);
Run Code Online (Sandbox Code Playgroud)

我不能请求facebook登录和google登录,或者从视图模型类请求startActivity intent,所以我创建了类接口AuthActivityListener:

public interface AuthActivityListener {
    void requestSignedIn();

    void requestGoogleAuth();

    void requestFacebookAuth();

    void requestShowDialogFragment(int type);
}
Run Code Online (Sandbox Code Playgroud)

在活动类中实现监听器:

AuthActivityRequester authRequestListener = new AuthActivityRequester() {
        @Override
        public void requestSignedIn() {
            Intent intent = new Intent(AuthActivity.this, ScanActivity.class);
            startActivity(intent);
            AuthActivity.this.finish();
        }

        @Override
        public void requestGoogleAuth() {
            Intent signInIntent = Auth.GoogleSignInApi.getSignInIntent(googleApiClient);
            startActivityForResult(signInIntent, GOOGLE_AUTH);
        } …
Run Code Online (Sandbox Code Playgroud)

android listener mvvm viewmodel android-activity

11
推荐指数
3
解决办法
2685
查看次数

e:[kapt]发生异常:android.databinding.tool.util.LoggedErrorException:发现数据绑定错误

我启用了数据绑定,但是在执行代码时出现此错误。

错误

e:[kapt]发生异常:android.databinding.tool.util.LoggedErrorException:发现数据绑定错误。

我创建了一个片段类和该类的XML。我能够导入datbindingutil类。

我已经完成了重建/与gradle文件同步/使缓存无效并重新启动,没有任何效果。

XML文件

<layout>

<!--suppress AndroidUnknownAttribute -->
<data class=".databinding.ProfileFragmentBinding">

    <variable
        name="user"
        type="com.sample.sample.user.User" />

    <variable
        name="vm"
        type="com.sample.sample.user.UserViewModel" />

    <variable
        name="handler"
        type="com.sample.sample.user.profile.ProfileFragment" />
</data>


<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <de.hdodenhof.circleimageview.CircleImageView
        android:id="@+id/profileIV"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="@dimen/medium"
        android:layout_marginTop="@dimen/medium"
        android:contentDescription="@null"
        android:src="@mipmap/ic_launcher_round"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:url="@{user.avatarUrl}" />

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:orientation="vertical"
        app:layout_constraintBottom_toBottomOf="@+id/profileIV"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="@+id/profileIV">

        <TextView
            android:id="@+id/profileNameLabel"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:fontFamily="@font/myriad_pro_semibold"
            android:text="@{user.name}"
            android:textColor="@color/black_transparent_de"
            android:textSize="@dimen/text_regular"
            tools:text="NAME" />

        <TextView
            android:id="@+id/badgeLabel"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="5dp"
            android:fontFamily="@font/myriad_pro_semibold"
            android:text="@{user.badge}"
            android:textColor="@color/grey_000000"
            android:textSize="@dimen/text_regular"
            tools:text="Superman" />

        <TextView
            android:id="@+id/profile_Label"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="5dp"
            android:fontFamily="@font/roboto_bold"
            android:text="@{user.badge}" …
Run Code Online (Sandbox Code Playgroud)

data-binding android viewmodel kotlin

11
推荐指数
2
解决办法
5161
查看次数

MVP/MVVM - 过滤列表,谁负责?

我正在实现一个显示项目列表的wpf应用程序,并提供通过键入文本框来过滤此列表的功能(我认为这是非常简单的用例).

我们正在使用MVVM结构.

我的问题是,谁负责过滤清单?视图还是视图模型?我应该在xaml.cs中实现"OnTextChanged"事件,还是应该在ViewModel中使用属性并使用PropertyChanged来过滤列表.
后续问题是,我应该在ViewModel中使用BindingList/ObservableCollection,还是使用ICollectionView将ItemsControl绑定到?

我尝试了两种方法,但它们都有效.赋予ViewModel责任使得View从代码中保持空白,但另一方面,我并不完全相信应用过滤是ViewModels的责任(例如:不同的视图可能需要不同的过滤)

有什么想法吗?

谢谢,罗尔

编辑:

把它放在ViewModel中让我困扰的是(在我当前的实现中)有一个System.Windows.Data的引用.这是我在ViewModel中没有的参考,因为它显然与View相关.或者我错过了什么?相关代码:

ICollectionView customerView = CollectionViewSource.GetDefaultView(customers);
Run Code Online (Sandbox Code Playgroud)

.net wpf model-view-controller mvvm viewmodel

10
推荐指数
1
解决办法
2710
查看次数

使用 navGraphViewModels 访问子 NavHostFragment 的图形范围的 ViewModel

我正在使用 Android Jetpack (2.2.0-alpha01) 的导航组件。

我希望使用嵌套在我的主 NavHostFragment 中的子 NavHostFragment,它配备了自己的子导航图。请查看以下图片了解上下文:

在此处输入图片说明

子导航主机在位于 MainNavHost 堆栈前端的片段中定义如下:

<fragment
    android:id="@+id/childNavHostFragment"
    android:name="androidx.navigation.fragment.NavHostFragment"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:defaultNavHost="false"
    app:navGraph="@navigation/child_graph" />
Run Code Online (Sandbox Code Playgroud)

在 CHILD Nav Host Fragment 前面的片段中,我尝试使用以下代码将 ViewModel 范围限定为 R.navigation.child_graph:

private val childGraphScopedViewModel: ChildGraphScopedViewModel by navGraphViewModels(R.navigation.child_graph) {
    viewModelFactory
}
Run Code Online (Sandbox Code Playgroud)

访问 childGraphScopedViewModel 时,我收到错误消息崩溃:

java.lang.IllegalArgumentException: No NavGraph with ID 2131689472 is on the NavController's back stack.
Run Code Online (Sandbox Code Playgroud)

我相信懒惰的 init 调用by navGraphViewModel()是在 mainGraph 中寻找导航图。

如何访问子 navHostFragment 范围的 ViewModel?感谢您的时间。

android viewmodel kotlin android-architecture-navigation android-navigation-graph

10
推荐指数
2
解决办法
4716
查看次数

在android中使用“by viewModels()”与“ViewModelProvider(this).get(ViewModel::class.java)”来查看模型初始化

我们可以ViewModel使用初始化类

private val viewModel: CharactersViewModel by viewModels()
Run Code Online (Sandbox Code Playgroud)

或者

viewModel = ViewModelProvider(this).get(CharactersViewModel::class.java)
Run Code Online (Sandbox Code Playgroud)

这里的 CharactersViewModel 是我们的 ViewModel 类。我的问题是什么时候使用哪个?两者都包含相同的目的吗?我已经阅读了 ViewModel 的 android 官方文档。文档说by viewModels()Kotlin 属性委托。但可惜没能看懂。任何人都可以帮助我理解这一点吗?

android mvvm viewmodel kotlin

10
推荐指数
2
解决办法
2190
查看次数