如何在 CommandBar 中动态更改图像的来源?

How can I dynamically change the Source of an Image within a CommandBar?

在网上搜索了一天后,我试着直接问你...

我用 C# 编写了一个 Windows 10 UWP 应用程序。我想显示 wifi 连接的强度。我有几张图片来展示这一点。 wifi强度应该显示在TopAppBar中。

我使用 MVVM 设置图像源。它适用于 UserControl 中的图像,但我无法在 CommandBar 中显示图像。

我有一个事件为我提供了实际图像的 Uri ("Picture")。

    private void WiFiInformationUpdated(object sender, WiFiInformationEventArgs args)
    {
        if (args.SSID != _viewModel.WifiInformationData.SSID)
        {
            _viewModel.WifiInformationData.SSID = args.SSID;
        }

        if (args.SignalBars != _viewModel.WifiInformationData.SignalBars)
        {
            _viewModel.WifiInformationData.SignalBars = args.SignalBars;
        }

        if(args.Picture != null)
        {
            Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal,() =>
            {
                var pic = new BitmapImage(args.Picture);
                _viewModel.WifiInformationData.Picture = pic;
            }
            );
        }
    }

这是它在 UserControl 中正常工作的地方:

<UserControl.DataContext>
    <Binding Path="Main" Source="{StaticResource Locator}"/>
</UserControl.DataContext>
<Image Source="{Binding WifiInformationData.Picture}" Grid.Row="1" Grid.Column="2" DataContextChanged="Image_DataContextChanged"/>

这是有问题的场景:

<Page.DataContext>
    <Binding Path="Main" Source="{StaticResource Locator}"/>
</Page.DataContext>
<Page.TopAppBar>
    <CommandBar HorizontalContentAlignment="Center" IsOpen="True" IsSticky="True" CompositeMode="Inherit">
        <CommandBar.ContentTemplate>
            <DataTemplate>
                <RelativePanel VerticalAlignment="Stretch" Width="200" >
                    <Image Source="{Binding Main.WifiInformationData.Picture, Source={StaticResource Locator}}" Width="20" RelativePanel.Below="tbPercentWifi" DataContextChanged="Image_DataContextChanged"/>
                </RelativePanel>
            </DataTemplate>
        </CommandBar.ContentTemplate>                        
    </CommandBar>
</Page.TopAppBar>

有什么建议吗?

解决方法是:

DataTemplate 访问问题...已修复:

public static class DataTemplateObjects
{
    public static DependencyObject FindChildControl<T>(DependencyObject control, string ctrlName)
    {
        int childNumber = VisualTreeHelper.GetChildrenCount(control);
        for (int i = 0; i < childNumber; i++)
        {
            DependencyObject child = VisualTreeHelper.GetChild(control, i);
            FrameworkElement fe = child as FrameworkElement;
            // Not a framework element or is null
            if (fe == null) return null;

            if (child is T && fe.Name == ctrlName)
            {
                // Found the control so return
                return child;
            }
            else
            {
                // Not found it - search children
                DependencyObject nextLevel = FindChildControl<T>(child, ctrlName);
                if (nextLevel != null)
                    return nextLevel;
            }
        }
        return null;
    }
}

然后在我的事件中设置图片来源:

    private void WiFiInformationUpdated(object sender, WiFiInformationEventArgs args)
    {
        if (args.SSID != _viewModel.WifiInformationData.SSID)
        {
            _viewModel.WifiInformationData.SSID = args.SSID;
        }

        if (args.SignalBars != _viewModel.WifiInformationData.SignalBars)
        {
            _viewModel.WifiInformationData.SignalBars = args.SignalBars;
        }

        if(args.Picture != null)
        {
            Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal,() =>
            {
                var pic = new BitmapImage(args.Picture);
                _viewModel.WifiInformationData.Picture = pic;
                Image img = DataTemplateObjects.FindChildControl<Image>(commandBar, "imgWifi") as Image;
                if (img == null) return;
                img.Source = pic;
            });
        }
    }