gpt4 book ai didi

c# - MVVM View 仅在 View 模型的构造函数中设置数据时更新

转载 作者:行者123 更新时间:2023-12-03 11:02:13 28 4
gpt4 key购买 nike

我假设这可能很容易,但我被卡住了。我有一个组合框,我可以在 viewmodel 的构造函数中更新其数据,但是如果在 viewmodel 初始化后设置数据,我将无法更新 View 。我认为这要么与我的 DataContext 或我的事件广播有关,但我要么遗漏了某些东西,要么不理解某些东西。

此外,我收到与我的“DataPane”属性相关的绑定(bind)路径错误,说在 RedViewModel 中找不到它。如果我在 RedViewModel 中放置 DataPane 的属性定义,控制台将停止提示,但代码在这两种情况下都有效。 DataPane 是我的 MainView 的 DataContext,而不是我的 RedView,所以我不太确定为什么会这样。这可能是也可能不是相关的背景信息;我最感兴趣的是这个问题的第一部分。

到目前为止,这是我的 XAML:

<UserControl x:Class="TableBuilder.Views.RedView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:views="clr-namespace:TableBuilder.Views"
xmlns:viewmodels="clr-namespace:TableBuilder.ViewModels"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<UserControl.DataContext>
<viewmodels:RedViewModel />
</UserControl.DataContext>
<StackPanel Background="Red">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="10" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="10" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="10" />
</Grid.ColumnDefinitions>

<TextBlock Text="Type:" Grid.Column="1" />
<TextBlock Text="Enumeration" Grid.Column="3" />
</Grid>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="10" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="10" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="10" />
</Grid.ColumnDefinitions>

<TextBlock Text="Value:" Grid.Column="1" />
<ComboBox Grid.Column="3" ItemsSource="{Binding EnumValueItems}" VerticalAlignment="Top">
</ComboBox>
</Grid>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="10" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="10" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="10" />
</Grid.ColumnDefinitions>

<TextBlock Text="Units:" Grid.Column="1" />
<TextBlock Text="Integer" Grid.Column="3" />
</Grid>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="10" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="10" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="10" />
</Grid.ColumnDefinitions>

<TextBlock Text="Description:" Grid.Column="1" />
<TextBlock Text="text" Grid.Column="3" />
</Grid>
</StackPanel>

这是 View 模型:
using System;
using System.Collections.ObjectModel;
using System.Windows;
using System.Windows.Data;
using TableBuilder.Helpers;
using TableBuilder.Models;

namespace TableBuilder.ViewModels
{
public class RedViewModel : ViewModelBase
{
private object _dataPane;
public object DataPane
{
get { return _dataPane; }
private set
{
_dataPane = value;
OnPropertyChanged(nameof(DataPane));
}
}
private ListCollectionView _enumValueItems;
public ListCollectionView EnumValueItems
{
get { return _enumValueItems; }
set
{
_enumValueItems = value;
OnPropertyChanged(nameof(EnumValueItems));
}
}
public bool Loaded { get; set; }

private ObservableCollection<string> _listData;

public ObservableCollection<string> ListData
{
get { return _listData; }
set
{
_listData = value;
EnumValueItems = new ListCollectionView(ListData);
//EnumValueItems.MoveCurrentTo(ListData[0]);
//OnPropertyChanged("ListData");
}
}

public RedViewModel()
{
//_listData = new ObservableCollection<string>();
//EnumValueItems = new ListCollectionView(_listData);
//EnumValueItems.CurrentChanged += enumValueItems_CurrentChanged;
//GetListData();
}
public void GetListData()
{
ListData = new ObservableCollection<string>();
RedModel model = new RedModel();
ListData = model.GetListData();
//EnumValueItems = new ListCollectionView(model.GetListData());
//EnumValueItems.MoveCurrentTo(ListData[0]);
//EnumValueItems.CurrentChanged += EnumValueItems_CurrentChanged;
}

private void EnumValueItems_CurrentChanged(object sender, EventArgs e)
{
if (Loaded)
{
MessageBox.Show((((ListCollectionView)sender).CurrentItem).ToString());
}
Loaded = true;
}
}
}

我的 ViewModelBase 类在这里:
using System.ComponentModel;
using TableBuilder.Models;
using TableBuilder.ViewModels;

namespace TableBuilder.Helpers
{
public class ViewModelBase : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;

protected void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
}

编辑:
这是我用来尝试修改列表数据的测试代码:
        public MainViewModel()
{
OpenCommand = new RelayCommand(ExecuteOpen);
ExitCommand = new RelayCommand(ExecuteExit);
var vm = new RedViewModel();
var test = new ObservableCollection<string>();
test.Add("Test1");
test.Add("Test2");
test.Add("Test3");
test.Add("Test4");
test.Add("Test5");
test.Add("Test6");
test.Add("Test7");
vm.EnumValueItems.Clear();
foreach (string s in test) { vm.EnumValueItems.Add(s); }
DataPane = vm;
}

我想我可能会以某种方式破坏这里的数据绑定(bind)。

编辑 2:

为了为问题提供进一步的背景和清晰度,以下是该程序的一般架构(无论好坏):

该程序是一个专门的 XML 解析器,用于基于 XML 定义为嵌入式软件创建配置表。屏幕右侧根据用户选择的树节点显示 XML 数据的相关部分。左侧将显示各种 View ,等待用户是否选择了 enum/float32/struct/etc 的变量。我现在感兴趣的代码是 Enum View ,因此有一个下拉菜单,可以根据 XML 定义填充可能的枚举值。

我想要做的是从 MainViewModel 填充 RedViewModel 中的下拉菜单(一旦我让一切按预期工作,它将成为我的枚举查看器清理)。如果我在 RedViewModel 的构造函数中填充列表,它似乎可以正确显示。但是,如果我在其他任何地方填充它(在我提供的示例中,我在实例化 RedViewModel 后将它填充到 MainViewModel 的构造函数中),它似乎不会更新。

最佳答案

EnumValueItems 分配一个新值将打破绑定(bind)。相反,您应该绑定(bind)到 ObservableCollection .然后清除项目并在更改时从其他集合中添加它们。

代替:

EnumValueItems = NewCollectionView

试试这个(更改为 ObservableCollection 后):
EnumValueItems.Clear();
foreach (ObjectType ob in NewCollection) {EnumValueItems.Add(ob);}

关于c# - MVVM View 仅在 View 模型的构造函数中设置数据时更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52488017/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com