参照框架
本文关键字:框架 | 更新日期: 2023-09-27 18:08:14
我试图在我的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 . xml .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的框架中。如果我尝试将代码移动到设置页面,我会得到一个nullreferenceexception,因为页面现在位于MyFrame中。谁有解决方案,我怎么才能让它工作?(我是c#编程新手;))
nullreferenceexception,因为页面现在位于MyFrame中。
这是因为您通过<Frame x:Name="MyFrame" />
在SplitView
中定义了MyFrame
,其中MyFrame
将是Frame
元素而不是ThemeAwareFrame
元素,因此当您尝试通过Frame as ThemeAwareFrame
获得它时,您得到null,因为您没有ThemeAwareFrame
对象,但您只有Frame
对象。
在Settings
页面上,如果你想改变当前框架MyFrame
的主题颜色,你需要将SplitView
内部的MyFrame
定义为ThemeAwareFrame
,如下所示:
<local:ThemeAwareFrame x:Name="MyFrame" Margin="0,5,0,0" />
如果你想改变rootFrame(Window.Current.Content
)的主题颜色,你需要像下面这样改变DarkTheme_OnClick
代码:
private void DarkTheme_OnClick(object sender, RoutedEventArgs e)
{
ThemeAwareFrame rootFrame = Window.Current.Content as ThemeAwareFrame;
rootFrame.AppTheme = ElementTheme.Dark;
}