科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道基础软件在 WPF 中创建可换肤的用户界面

在 WPF 中创建可换肤的用户界面

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

这篇文章讨论的是在WPF中如何创建可以在运行时”换肤”的用户界面的一些基础知识,我们将验证WPF对用户界面”皮肤”的支持……

作者:周银辉 来源:博客园 2007年11月19日

关键字:

  • 评论
  • 分享微博
  • 分享邮件
允许用户更改皮肤的上下文菜单被定义在MainWindow的XAML文件中,如下所示:

以下是引用片段:
<Grid.ContextMenu>
  <ContextMenu MenuItem.Click="OnMenuItemClick">
    <MenuItem Tag=".\Resources\Skins\BlackSkin.xaml" IsChecked="True">
      <MenuItem.Header>
        <Rectangle Width="120" Height="40" Fill="Black" />
      </MenuItem.Header>
    </MenuItem>
    <MenuItem Tag=".\Resources\Skins\GreenSkin.xaml">
      <MenuItem.Header>
        <Rectangle Width="120" Height="40" Fill="Green" />
      </MenuItem.Header>
    </MenuItem>
    <MenuItem Tag=".\Resources\Skins\BlueSkin.xaml">
      <MenuItem.Header>
        <Rectangle Width="120" Height="40" Fill="Blue" />
      </MenuItem.Header>
    </MenuItem>
  </ContextMenu>
</Grid.ContextMenu>

  当用户在菜单中选择一个新的"皮肤"时,在MainWindow的后台代码文件中以下代码将被执行:

以下是引用片段:
  void OnMenuItemClick(object sender, RoutedEventArgs e)
  {
   MenuItem item = e.OriginalSource as MenuItem;
  
   // Update the checked state of the menu items.
   Grid mainGrid = this.Content as Grid;
   foreach (MenuItem mi in mainGrid.ContextMenu.Items)
   mi.IsChecked = mi == item;
  
   // Load the selected skin.
   this.ApplySkinFromMenuItem(item);
  }
  
  void ApplySkinFromMenuItem(MenuItem item)
  {
   // Get a relative path to the ResourceDictionary which
   // contains the selected skin.
   string skinDictPath = item.Tag as string;
   Uri skinDictUri = new Uri(skinDictPath, UriKind.Relative);
  
   // Tell the Application to load the skin resources.
   DemoApp app = Application.Current as DemoApp;
   app.ApplySkin(skinDictUri);
  }
  
  DemoApp对象的ApplySkin方法的调用将导致下面的代码被执行:
  public void ApplySkin(Uri skinDictionaryUri)
  {
   // Load the ResourceDictionary into memory.
   ResourceDictionary skinDict =
   Application.LoadComponent(skinDictionaryUri) as ResourceDictionary;
  
   Collection mergedDicts =
   base.Resources.MergedDictionaries;
  
   // Remove the existing skin dictionary, if one exists.
   // NOTE: In a real application, this logic might need
   // to be more complex, because there might be dictionaries
   // which should not be removed.
   if (mergedDicts.Count > 0)
   mergedDicts.Clear();
  
   // Apply the selected skin so that all elements in the
   // application will honor the new look and feel.
   mergedDicts.Add(skinDict);
  }

  现在我们来看一个界面元素如何使用皮肤资源的例子,下面的XAML代码诚信了窗口左边的"Agents"区域,其包含了一个包含保险业代理商名字的下拉列表控件,其标题为"Agents".

以下是引用片段:
<UserControl 
  x:Class="SkinnableApp.AgentSelectorControl"
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  >
  <Border <STRONG>Style="{DynamicResource styleContentArea}"</STRONG>>
    <Grid>
      <Grid.RowDefinitions>
        <RowDefinition Height="Auto" />
        <RowDefinition Height="*" />
      </Grid.RowDefinitions>

      <!-- AGENT SELECTOR HEADER -->
      <Border <STRONG>Style="{DynamicResource styleContentAreaHeader}"</STRONG>>
        <StackPanel Orientation="Horizontal">
          <Image 
            Margin="4,4,0,4" 
            Source=".\Resources\Icons\agents.ico" 
            />
          <TextBlock 
            FontSize="20" 
            Padding="8" 
            Text="Agents" 
            VerticalAlignment="Center"
            />
        </StackPanel>
      </Border>

      <!-- AGENT SELECTION LIST -->
      <ListBox
        Background="Transparent"
        BorderThickness="0"
        Grid.Row="1"
        IsSynchronizedWithCurrentItem="True"
        ItemsSource="{Binding}"
        <STRONG>ItemTemplate="{DynamicResource agentListItemTemplate}"
</STRONG>        ScrollViewer.HorizontalScrollBarVisibility="Hidden" 
        />
    </Grid>
  </Border>
</UserControl>

    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章