如何在Mahapps.Metro标题栏中使用XAML资源作为图标?

时间:2015-12-23 13:13:47

标签: c# wpf xaml mahapps.metro xaml-resources

我有一个小应用程序,使用Mahapps Metro Framework。我想更改标题栏中的图标,如连接/断开图标。如何访问内容或动态绑定它?

这是我的XAML:

class Mydata 

{

ArrayList<AppInfo> data;

    public Mydata (List<AppInfo> data) {

        this.data= data;

    }

    public List<AppInfo> getContactSyn() {
        return data;
    }

    public void setContactSyn(List<AppInfo> data) {
        this.data= data;
    }


}

 Gson gson = new Gson();
MyData datalist = new MyData(data);

    String jsonData = gson.toJson(datalist);

另外:我没有ImageFile(没有* .ico),我使用Mahapps.Resources(xaml-Files)中包含的资源。 Afaik必须以某种方式替换Rectangle的内容 - 但是如何?

2 个答案:

答案 0 :(得分:3)

您可以通过将图标资源保留在ViewModel并使用常规绑定来实现这一目标:

XAML:

<Controls:MetroWindow x:Class="WpfApplication4.Window4"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:Controls="http://metro.mahapps.com/winfx/xaml/controls"
    xmlns:local="clr-namespace:WpfApplication4"
    mc:Ignorable="d"
    BorderThickness="5"        
    BorderBrush="{DynamicResource AccentColorBrush}"
    Title="{Binding MyIcon}" Height="300" Width="300" Loaded="MetroWindow_Loaded">
<Window.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Colors.xaml" />
            <ResourceDictionary Source="pack://application:,,,/MahApps.Metro.Resources;component/Icons.xaml" />
            <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Accents/Olive.xaml" />
            <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Accents/BaseDark.xaml" />
        </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>
</Window.Resources>

<Controls:MetroWindow.LeftWindowCommands>
    <Controls:WindowCommands>
        <Rectangle Height="20" Width="20" Fill="{Binding RelativeSource={RelativeSource AncestorType=Controls:WindowCommands}, Path=Foreground}">
            <Rectangle.OpacityMask>
                <VisualBrush Stretch="Fill" Visual="{Binding MyResource}" />
            </Rectangle.OpacityMask>
        </Rectangle>
    </Controls:WindowCommands>
</Controls:MetroWindow.LeftWindowCommands>

<Controls:MetroWindow.DataContext>
    <local:MyViewModel/>
</Controls:MetroWindow.DataContext>

<Grid>
    <Button Content="Change Icon" Click="Button_Click" HorizontalAlignment="Center" VerticalAlignment="Center"></Button>
</Grid>

窗口:

public partial class Window4 : MetroWindow
{
    MyViewModel viewModel;

    public Window4()
    {
        InitializeComponent();
    }

    private void MetroWindow_Loaded(object sender, RoutedEventArgs e)
    {
        viewModel = new MyViewModel();
        DataContext = viewModel;

        viewModel.MyIcon = "appbar_box";
        viewModel.MyResource = (Visual)Resources[viewModel.MyIcon]; 
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        if (viewModel.MyIcon == "appbar_box")
            viewModel.MyIcon = "appbar_add";
        else viewModel.MyIcon = "appbar_box";

        viewModel.MyResource = (Visual)Resources[viewModel.MyIcon];
    }
}

视图模型:

public class MyViewModel : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    public MyViewModel()
    {
    }

    private string myIcon;
    public string MyIcon
    {
        get { return myIcon; }
        set
        {
            if (value != myIcon)
            {
                myIcon = value;
                NotifyPropertyChanged();
            }
        }
    }

    private Visual myResource;
    public Visual MyResource
    {
        get { return myResource; }
        set
        {
            if (value != myResource)
            {
                myResource = value;
                NotifyPropertyChanged();
            }
        }
    }

    private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

enter image description here enter image description here

答案 1 :(得分:0)

虽然这个问题已经接受了答案,但这是我的解决方案,它不需要MetroWindow部分类中的代码(尽管它确实需要在视图模型中引用System.Windows并使用Application Dispatcher)

using System;
using Caliburn.Micro;
using System.Windows.Media;
using System.Windows;

namespace ChangingMahAppsIcon
{
    class CHeartbeatViewModel : PropertyChangedBase
    {
        public Visual IconResource { get; set; }

        private System.Timers.Timer m_oHeartbeatTimer;
        private ResourceDictionary m_oIconResource;
        private bool m_bHeartbeatIsOn = false;

        public CHeartbeatViewModel()
        {
            m_oIconResource = new ResourceDictionary() { Source = new Uri(@"Resources\Icons.xaml", UriKind.Relative) };

            m_oHeartbeatTimer = new System.Timers.Timer(1000);
            m_oHeartbeatTimer.Elapsed += UpdateHeartbeat;

            m_oHeartbeatTimer.Start();

        }

        private void UpdateHeartbeat(object sender, System.Timers.ElapsedEventArgs e)
        {
            string strIconName;
            m_bHeartbeatIsOn = !m_bHeartbeatIsOn;
            if (m_bHeartbeatIsOn)
            {
                strIconName = "appbar_heart";
            }
            else
            {
                strIconName = "appbar_heart_outline";
            }

            Application.Current.Dispatcher.Invoke((System.Action)delegate {

                IconResource = (Visual)m_oIconResource[strIconName];
                NotifyOfPropertyChange(() => IconResource);
            });

        }
    }
}