参考帧

时间:2016-09-22 14:12:46

标签: c# uwp

我正在尝试在我的UWP 10应用中创建一个设置,以便用户可以在运行时更改应用主题。我发现了一篇有趣的文章http://www.guruumeditation.net/en/changing-app-theme-on-the-fly-with-requestedtheme/,其中有一个名为 ThemeAwareFrame 的公共类:

public class ThemeAwareFrame : Frame
{
    private static readonly ThemeProxyClass _themeProxyClass = new ThemeProxyClass();
 
    public static readonly DependencyProperty AppThemeProperty = DependencyProperty.Register(
        "AppTheme", typeof (ElementTheme), typeof (ThemeAwareFrame),
 new PropertyMetadata(default(ElementTheme), (d,e) => _themeProxyClass.Theme = (ElementTheme)e.NewValue));
 
 
    public ElementTheme AppTheme
    {
        get { return (ElementTheme) GetValue(AppThemeProperty); }
        set { SetValue(AppThemeProperty, value); }
    }
 
    public ThemeAwareFrame()
    {
        var themeBinding = new Binding { Source = _themeProxyClass, Path = new PropertyPath("Theme") };
        SetBinding(RequestedThemeProperty, themeBinding);
    }
 
    // Proxy class to be used as singleton
    sealed class ThemeProxyClass : INotifyPropertyChanged
    {
        private ElementTheme _theme;
 
        public ElementTheme Theme
        {
            get { return _theme; }
            set
            {
                _theme = value;
                OnPropertyChanged();
            }
        }
 
        public event PropertyChangedEventHandler PropertyChanged;
 
        private void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

App.xaml.cs 文件中,它的引用如下:

            Frame rootFrame = Window.Current.Content as Frame;

        if (rootFrame == null)
        {

            rootFrame = new ThemeAwareFrame();

            rootFrame.NavigationFailed += OnNavigationFailed;

            if (e.PreviousExecutionState == ApplicationExecutionState.Terminated)
            {
                //TODO: Load state from previously suspended application
            }

            // Place the frame in the current Window
            Window.Current.Content = rootFrame;

        }

        if (e.PrelaunchActivated == false)
        {
            if (rootFrame.Content == null)
            {
                rootFrame.Navigate(typeof(Shell), e.Arguments);
            }

            Window.Current.Activate();
        }
    }

在不同的页面上,可以使用以下代码更改应用主题:

(Frame as ThemeAwareFrame).AppTheme = ElementTheme.Light;

(Frame as ThemeAwareFrame).AppTheme = ElementTheme.Dark;

如果使用名为Shell的页面上的事件处理代码,则代码可以正常工作。但是,在我的应用程序中,Shell充当带有SplitView菜单的导航页面,并将不同的页面(例如“设置”)加载到名为MyFrame的Frame中。如果我尝试将代码移动到“设置”页面,我会得到一个NullReferenceExeption,因为该页面现在位于MyFrame中。 有没有人有解决方案我怎么能让这个工作? (我是c#编程的新手;))

1 个答案:

答案 0 :(得分:0)

  

NullReferenceExeption,因为该页面现在位于MyFrame中。

这是因为您在MyFrame SplitView<Frame x:Name="MyFrame" />定义了MyFrame Frame ThemeAwareFrame元素而不是Frame as ThemeAwareFrame元素,所以当你试图通过ThemeAwareFrame获取它时,你得到了null,因为你没有Frame个对象,但你只有Settings个对象。

MyFrame页面上,如果要更改当前框架MyFrame的主题颜色,则需要将SplitView内的ThemeAwareFrame定义为<local:ThemeAwareFrame x:Name="MyFrame" Margin="0,5,0,0" /> 如下:

Window.Current.Content

如果您想更改rootFrame(DarkTheme_OnClick)的主题颜色,则需要更改private void DarkTheme_OnClick(object sender, RoutedEventArgs e) { ThemeAwareFrame rootFrame = Window.Current.Content as ThemeAwareFrame; rootFrame.AppTheme = ElementTheme.Dark; } 代码,如下所示:

DiagnosticSeverity.Error