簡體   English   中英

app.xaml.cs與MainViewmodel通訊出現問題

[英]Issue with app.xaml.cs to MainViewmodel communication

我在wpf App.xaml.cs文件中遵循以下代碼:

 void App_DispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
        {
            var mainVM = MainWindowViewModel.Instance;
            mainVM.DisplayMessage = string.Format("Something went wrong and it has been logged...If the problem persists, please contact {0}.", mainVM.NotificationsReceiver);
            mainVM.DisplayMessageForegroundColor = "Red";

        e.Handled = true;
    }

MainWindowViewModel.cs

public string DisplayMessage
        {
            get
            {
                return m_displayMessage;
            }
            set
            {
                m_displayMessage = value;
                OnPropertyChanged("DisplayMessage");

            }
        }

        public string DisplayMessageForegroundColor
        {
            get
            {
                return m_displayMessageForegroundColor;
            }
            set
            {
                m_displayMessageForegroundColor = value;
                OnPropertyChanged("DisplayMessageForegroundColor");

            }
        }

MainWindow.xaml

 <Label Content="{Binding DisplayMessage}" Foreground="{Binding DisplayMessageForegroundColor}" Grid.Column="1" HorizontalAlignment="Left" Height="33" Margin="14,660,0,0" Grid.Row="1" 
           VerticalAlignment="Top" Width="693" Grid.ColumnSpan="3"/>

但這似乎不起作用。盡管正在調用app.xaml.cs中的方法,但我沒有在UI上看到顯示消息的錯誤,請問這里可能出什么問題了? (不過,從MainWindowViewModel內設置DisplayMessage和DisplayMessageForegroundColor屬性時,我可以看到該消息)。

請指教。

謝謝。

問題是您編寫了具有singleton Instance的singleton視圖模型,但隨后不使用它。 而是在XAML中創建視圖模型的新實例:

<Window.DataContext>
    <MainViewModel:MainWindowViewModel />
</Window.DataContext>

這將創建MainWindowViewModel的新實例。 如果您的XAML具有<TextBox .../> ,您是否認為世界上只有一個TextBox ,您只是將其放在一個新位置? 當然不是。 您正在創建一個新的TextBox 其他任何XAML元素也是如此。

修復很容易:首先,刪除我上面引用的Window.DataContext元素。

然后將靜態單例視圖模型分配給DataContext

<Window
    ...etc...
    xmlns:MainViewModel="clr-namespace:Whatever.Namespace.YourViewModel.IsIn"
    DataContext="{x:Static MainViewModel:MainWindowViewModel.Instance}"
    ...etc...
    >

要么:

<Window.DataContext>
    <x:StaticExtension 
        Member="MainViewModel:MainWindowViewModel.Instance" />
</Window.DataContext>

<x:StaticExtension ...{x:Static... System.Windows.Markup.StaticExtensionMarkupExtension子類。 如果其中之一在類名上具有Extension后綴,則XAML允許您在將其用作花括號之間的標記擴展名時忽略名稱的該部分。 嘗試這個; 它會工作:

DataContext="{x:StaticExtension MainViewModel:MainWindowViewModel.Instance}"

一樣。 BindingSystem.Windows.Data.Binding )也是MarkupExtension 因此,您可以在XAML的屬性值中使用大括號創建一個:

<TextBox Text="{Binding Foo}" />

Text="{Binding Foo}"創建System.Windows.Data.Binding的實例。 但是Binding在類名上沒有Extension后綴。 這不是必需的,只是XAML提供的便利(如果您想使用它)。

要點:每當在XAML中看到Property="{Identifier ...}"時, Identifier都是派生自System.Windows.Markup.MarkupExtension的類。 它的實際名稱可能是IdentifierIdentifierExtension ,花括號正在創建和初始化它的實例。

好,回到您的錯誤。

讓我們從中學習。

當您嘗試編寫單例類時,需要防止其他類創建它的實例,因此您最終不會遇到這樣的事情。 最簡單,最好的方法是將MainWindowViewModel的構造函數設為私有:

public class MainWindowViewModel : ViewModelBaseOrWhatever
{
    //  If MainWindowViewModel has no public constructors, no other class can create an 
    //  instance of it. This is a requirement you need to enforce, so and you can make 
    //  the compiler enforce it for you. If you had done this, the compiler would have 
    //  found this bug for you as soon as you wrote it. 
    private MainWindowViewModel()
    {
        //  ...whatever...
    }

    static MainWindowViewModel()
    {
        Instance = new MainWindowViewModel();
    }

    public static MainWindowViewModel Instance { get; private set; }
}

單身

關於單例類,明智的是通過將構造函數設為私有並在靜態構造函數中創建Instance來增強其單例性質:

private MySingletonViewModel()
{
    //  stuff
}

public static MySingletonViewModel Instance { get; private set; }

//  Static constructor
static MySingletonViewModel()
{
    Instance = new MySingletonViewModel();
}

當您執行此操作時,編譯器已在計划中,它不會讓您意外創建第二個實例:

在這里,編譯器會抱怨:

“ MySingletonViewModel.MySingletonViewModel()”由於其保護級別而無法訪問。

第一次看到您會說“嗯?!”,但是大多數錯誤消息都是如此。

public SomeOtherClass() 
{
    var x = new MySingletonViewModel();
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM