Wpf Xaml view не обновляется - PullRequest
1 голос
/ 15 ноября 2011

У меня есть заставка, которая должна показывать процесс загрузки при запуске программы. Не удается получить текст в метке для обновления при загрузке компонентов.

Из основного запуска program.cs Я вызываю метод run () в контроллере заставки.

startUpSplash.Run();

Вот контроллер. Это показывает заставку с надписью «Initializing ...»

 public class StartUpSplashController
{
    public StartUpSplashViewModel ViewModel { get; set; }

    private StartUpSplashView starUpSplashWindow = new StartUpSplashView();
    private delegate void UIDelegate();
    public void Run()
    {
        InitializeViewModel();

        ViewModel.StatusMessage = "Initializing...";

        starUpSplashWindow.DataContext = ViewModel;
        starUpSplashWindow.Show();
    }



    public void UpdateStatus(string statusMessage)
    {
        starUpSplashWindow.Dispatcher.Invoke(new UIDelegate(delegate { ViewModel.StatusMessage = statusMessage; }));
        //ViewModel.StatusMessage = statusMessage;
    }

    public void End()
    {
        starUpSplashWindow.Close();
        starUpSplashWindow.InvalidateVisual();
    }

    private void InitializeViewModel()
    {
        ViewModel = new StartUpSplashViewModel(starUpSplashWindow);
        ViewModel.Controller = this;
    }
}

Затем из основного файла program.cs по-разному происходит вызов этого метода UpdateStatus также в контроллере заставки. Это предназначено для обновления метки, чтобы показать все происходящее.

Это Xaml для lbl, который должен обновляться.

 <Label Content="{Binding Path=StatusMessage, Mode=TwoWay, UpdateSourceTrigger= PropertyChanged}"  />

Метка не обновляется при вызове метода UpdateStatus. Я заметил одну странную вещь: если бы я сделал

startupSplash.UpdateStatus("something");

, а затем

Messagebox.show("something"); 

Экран-заставка показывает обновленную метку после появления окна сообщения.

Любая помощь с этим будет оценена.

ОБНОВЛЕНИЕ 2: Вот модель представления

public class StartUpSplashViewModel : ViewModel<IView>
{
    [ImportingConstructor]
    public StartUpSplashViewModel(StartUpSplashView view)
        : base(view)
    {
    }

    public StartUpSplashController Controller { get; set; }

    private string _statusMessage;
    public string StatusMessage
    {
        get
        {
            return _statusMessage;
        }
        set
        {
            if (_statusMessage == value)
                return;

            _statusMessage = value;
            this.RaisePropertyChanged(s => s.StatusMessage);
        }
    }
}

Ответы [ 3 ]

1 голос
/ 16 ноября 2011

Вы пытались поместить обновление в запущенную ветку пользовательского интерфейса заставки?Для этого вы можете использовать метод Dispatcher.Invoke.Во-первых, вы должны объявить делегата:

private delegate void UIDelegate();

Затем вы используете этот делегат в Dispatcher:

starUpSplashWindow.Dispatcher.Invoke(new UIDelegate(delegate
{
    ViewModel.StatusMessage = statusMessage;
}));

Это вызовет обновление в потоке, выполняющем пользовательский интерфейс, и этообычно обеспечивает надлежащее обновление пользовательского интерфейса.

0 голосов
/ 17 ноября 2011

Вот как я решил эту проблему.

Я добавил другой метод к splashScreenController и вызвал его из UpdateStatus после установки сообщения ViewModel.Status.

 [SecurityPermissionAttribute(SecurityAction.Demand, Flags = SecurityPermissionFlag.UnmanagedCode)]
    public void DoEvents()
    {
        DispatcherFrame frame = new DispatcherFrame();
        Dispatcher.CurrentDispatcher.BeginInvoke(DispatcherPriority.Background,
            new DispatcherOperationCallback(ExitFrame), frame);
        Dispatcher.PushFrame(frame);
    }

    public object ExitFrame(object f)
    {
        ((DispatcherFrame)f).Continue = false;

        return null;
    }
0 голосов
/ 16 ноября 2011

Я не уверен, что это сработает, поскольку я не пробовал, но надеюсь, что это сработает, пожалуйста, попробуйте:

Создайте метод RefreshDelegate и Refresh внутри файла SplashWindow.xaml.cs View следующим образом:

// To Refresh the UI immediately
private delegate void RefreshDelegate();
private static void Refresh(DependencyObject obj)
{
    obj.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Render,
        (RefreshDelegate)delegate { });
}

Измените ваш метод UpdateStatus в контроллере следующим образом:

public void UpdateStatus(string statusMessage)
{    
    ViewModel.StatusMessage = statusMessage;
    starUpSplashWindow.Refresh(starUpSplashWindow.statusLabel); //where statusLabel is the name of the Label
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...