C# WPF列表框未更新

C# WPF列表框未更新,c#,wpf,C#,Wpf,我在这个论坛上搜索了一下,但是我找不到适合我的特定场景的解决方案 我试图理解WPF和MVVM,并为此构建了一个简单的WPF 我的数据模型是(我在这里实现了INotifyPropertyChanged,构造函数初始化所有属性): My ViewModel(由WPF代码隐藏使用): 名称空间MyApp.ui.ViewModels { 公共类服务器VIEWMODEL { 专用可观测采集服务器; 公共可观测收集服务器 { 获取{return server;} 设置{server=value;} } 公共

我在这个论坛上搜索了一下,但是我找不到适合我的特定场景的解决方案

我试图理解WPF和MVVM,并为此构建了一个简单的WPF

我的数据模型是(我在这里实现了INotifyPropertyChanged,构造函数初始化所有属性):

My ViewModel(由WPF代码隐藏使用):

名称空间MyApp.ui.ViewModels
{
公共类服务器VIEWMODEL
{
专用可观测采集服务器;
公共可观测收集服务器
{
获取{return server;}
设置{server=value;}
}
公共服务器viewmodel()
{
Servers=新的ObservableCollection
{
新服务器(001,“Server001”,“192.168.254.3”),
新服务器(002,“服务器002”,“100.92.0.200”),
新服务器(003,“Server003”,“64.32.0.3”),
新服务器(004,“Server004”,“172.10.0.4”),
新服务器(005,“Server005”,“165.23.0.233”),
新服务器(006,“Server006”,“81.22.22.6”),
新服务器(007,“Server007”,“10.10.0.7”)
};
}
public void ChangeServerNames()
{
//变动前
foreach(服务器中的var项)
{
MessageBox.Show(item.Name);
}
整数计数=1000;
foreach(服务器中的var项)
{
item.Name=“Server”+count.ToString();
计数+=1000;
}
//变动后
foreach(服务器中的var项)
{
MessageBox.Show(item.Name);
}
}
}
}
我的WPF主视图(主菜单)使用以下XAML代码加载自定义用户控件(ExplorerView)(包含一个列表框,每个列表框项包含1个复选框+图像+文本块)


最后,MainView代码将加载ServersViewModel,以便ExplorerView控件可以绑定数据

namespace MyApp.ui
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public ServersViewModel context { get; set; }

        public MainWindow()
        {
            InitializeComponent();

            context = new ServersViewModel();
            DataContext = context;
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            context.ChangeServerNames();
        }
    }
}
名称空间MyApp.ui
{
/// 
///MainWindow.xaml的交互逻辑
/// 
公共部分类主窗口:窗口
{
公共服务器viewmodel上下文{get;set;}
公共主窗口()
{
初始化组件();
context=newserversviewmodel();
DataContext=context;
}
私有无效按钮\u单击(对象发送者,路由目标e)
{
context.ChangeServerNames();
}
}
}
也就是说,我有两个问题:

1) 如您所见,在MainView中,我实现了一个按钮单击事件,该事件调用ServersViewModel.ChangeServerNames()方法。问题是ExplorerView控件中的文本块不显示更新的数据

I ChangeServerNames()我还使用MessageBox显示更改前后的值,并且我看到值正在更改,不确定ListBox/TextBlock为什么没有更新。。。!!!(我已经测试了许多其他可能的解决方案,但我无法让它工作…)

2) 我读到MainView(和所有其他视图)中的代码隐藏应该只包含InitializeComponent();和“DataContext=context;”的最大值。。。 如果这是真的,那么按钮点击事件和其他事件应该放在哪里

最后,主窗口XAML的代码:

<Window
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:MyApp.ui"
        xmlns:Views="clr-namespace:MyApp.ui.Views"
        x:Class="MyApp.ui.MainWindow"
        mc:Ignorable="d"
        Title="Server" MinHeight="720" MinWidth="1024"
        Height ="720" Width="1024">
    <Grid Margin="2">

        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="200" />
            <ColumnDefinition Width="Auto"/>
            <ColumnDefinition />
        </Grid.ColumnDefinitions>

        <Grid.RowDefinitions>
            <RowDefinition Height="41*"/>
            <RowDefinition Height="608*"/>
            <RowDefinition Height="30"/>
        </Grid.RowDefinitions>

        <GridSplitter Grid.Column="1" Grid.Row="1"
              HorizontalAlignment="Center"
              VerticalAlignment="Stretch"
              Background="Gray" 
              ShowsPreview="True"
              Width="4" Margin="0,2,0,4"
              />

        <Views:MenuView Grid.ColumnSpan="3"/>
        <Views:FooterView Grid.Row="2" Grid.ColumnSpan="3" />
        <Views:ExplorerView Grid.Column="0" Grid.Row="1" />

        <!--Temp Tests-->
        <StackPanel Margin="12" Grid.Column="3" Grid.Row="1" Width="Auto" Height="Auto" Orientation="Horizontal" VerticalAlignment="Top" HorizontalAlignment="Left">
            <Button Margin="4" Width="120" Height="30" Content="Change Data Test..." Click="Button_Click" />
        </StackPanel>

    </Grid>
</Window>


谢谢您抽出时间……

好的,我发现了问题

而不是

set { name = value; OnPropertyChanged(Name); }
set { ipAddress = value; OnPropertyChanged(IPAddress); }
我在方法调用中缺少字符串参数的引号 正确的形式是

set { name = value; OnPropertyChanged("Name"); }
set { ipAddress = value; OnPropertyChanged("IPAddress"); }
奇怪的是编译器没有抛出任何错误。。。。方法 私有void OnPropertyChanged(字符串propertyName) 是“询问”字符串作为输入参数

无论如何,避免这些错误(我发现)的最好方法是这样编写事件(调用者提供自己的公共名称):

现在我可以做了

set { name = value; OnPropertyChanged(); }
set { ipAddress = value; OnPropertyChanged(); }

谢谢。

好的,我发现了问题

而不是

set { name = value; OnPropertyChanged(Name); }
set { ipAddress = value; OnPropertyChanged(IPAddress); }
我在方法调用中缺少字符串参数的引号 正确的形式是

set { name = value; OnPropertyChanged("Name"); }
set { ipAddress = value; OnPropertyChanged("IPAddress"); }
奇怪的是编译器没有抛出任何错误。。。。方法 私有void OnPropertyChanged(字符串propertyName) 是“询问”字符串作为输入参数

无论如何,避免这些错误(我发现)的最好方法是这样编写事件(调用者提供自己的公共名称):

现在我可以做了

set { name = value; OnPropertyChanged(); }
set { ipAddress = value; OnPropertyChanged(); }

谢谢。

IPAddress
是一个字符串。遗憾的是,编译器无法为您做任何事情。您是对的,CallerMemberName是正确的答案,这是一个用于创建类型化viewmodel属性的VS代码段。
IPAddress
是一个字符串。遗憾的是,编译器无法为您做任何事情。您是对的,CallerMemberName是正确的答案——这是一个用于创建类型化viewmodel属性的VS代码段。
set { name = value; OnPropertyChanged(); }
set { ipAddress = value; OnPropertyChanged(); }