为什么我的ObservableCollection不能更新我的UI?

时间:2018-05-18 05:04:14

标签: c# .net wpf mvvm data-binding

我很确定我错过了一些非常小的东西,但我不知道我的生活中我找错了。

我试图将我的datagrid绑定到ConsoleLines属性,该属性实际上是对它的输入,我调试它并且ConsoleLines包含多个字符串。 但由于某种原因,它没有更新UI并将行添加到gridview ..或者技术上很好的TextBlock。

所以我的MainWindows设置就像这样

public partial class MainWindow : Window
    {
        Server Server = new Server();
        public MainWindow()
        {
            InitializeComponent();
            DataContext = new MasterViewModel();
        }

        private void BtnStart_OnClick(object sender, RoutedEventArgs e)
        {
            Server.StartServer();
        }
    }

正如您所看到的,我将DataContext设置为MasterViewModel的新实例,如下所示

public class MasterViewModel
    {
        public Server Server { get; }
            = new Server();
    }

这是我的服务器类

public class Server : INotifyPropertyChanged
    {
        public Process pServer;
        public Server()
        {

        }

        public ObservableCollection<string> ConsoleLines { get; }
            = new ObservableCollection<string>();

        public void StartServer()
        {
            pServer = new Process();

            pServer.StartInfo.FileName = "java";
            pServer.StartInfo.Arguments = @"-jar " + "-Xms512M -Xmx1G spigot.jar";
            pServer.StartInfo.UseShellExecute = false;
            pServer.StartInfo.RedirectStandardOutput = true;
            pServer.StartInfo.RedirectStandardError = true;
            pServer.StartInfo.RedirectStandardInput = true;

            pServer.OutputDataReceived += OKDataReceived;
            pServer.ErrorDataReceived += ErrorDataReceived;

            pServer.Start();

            pServer.BeginErrorReadLine();
            pServer.BeginOutputReadLine();
        }

        private void ErrorDataReceived(object sender, DataReceivedEventArgs e)
            => Application.Current.Dispatcher.Invoke(() => ConsoleLines.Add($"ERROR: {e.Data}"));

        private void OKDataReceived(object sender, DataReceivedEventArgs e)
            => Application.Current.Dispatcher.Invoke(() => ConsoleLines.Add($"MESSAGE: {e.Data}"));

        public event PropertyChangedEventHandler PropertyChanged;
        [NotifyPropertyChangedInvocator]
        private void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }

据我所知,一切都设置正确,我看不出任何错误。

这是我的XAML

<DataGrid ItemsSource="{Binding Server.ConsoleLines}" Width="400" Margin="182,109,210,68">
            <DataGrid.Columns>
                <DataGridTemplateColumn>
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <TextBlock Text="{Binding}"></TextBlock>
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                </DataGridTemplateColumn>
            </DataGrid.Columns>
        </DataGrid>
        <Button Name="BtnStart" Click="BtnStart_OnClick" Content="Start Server" HorizontalAlignment="Left" Margin="365,388,0,0" VerticalAlignment="Top" Width="75"/>

EDIT 初始化服务器的新实例,然后使用Button在新实例上启动方法似乎是个问题..我不知道为什么。

1 个答案:

答案 0 :(得分:0)

您应该从MainWindow中删除Server字段,然后启动DataContext中的服务器。

private void BtnStart_OnClick(object sender, RoutedEventArgs e)
{
    ((MasterViewModel)DataContext).Server.StartServer();
}

或者,像这样初始化视图模型:

DataContext = new MasterViewModel { Server = Server };

将Server字段值分配给视图模型中的Server属性(必须读/写)。否则你有两个服务器实例。