【问题标题】:Bind image source dynamically动态绑定图片源
【发布时间】:2014-09-29 16:07:02
【问题描述】:

我想为我的 WP8 应用程序创建一个函数,告诉用户 GPS 信号是否正在初始化、准备就绪等。我想用一张小图片、问号(如果仍在搜索)、X(如果没有数据)和一个如果确定,请勾选。我正在使用 MVVM Light。

这是我目前所拥有的:

在我看来,我有以下几行:

...
DataContext="{Binding Signal, Source={StaticResource Locator}}">
...
<Image Source="{Binding Signalstrength.Imageuri, Converter={StaticResource SignalstatusConverter}}" Width="38" Height="38" HorizontalAlignment="Right" Grid.Column="1" />

我已经创建了一个转换器:

public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        string path = System.Convert.ToString(value);

        if (App.Geolocator != null)
        {
            switch (App.Geolocator.LocationStatus)
            {
                case Windows.Devices.Geolocation.PositionStatus.Disabled:
                    path = "/Assets/close.png";
                    break;
                case Windows.Devices.Geolocation.PositionStatus.Initializing:
                    path = "/Assets/questionmark.png";
                    break;
                case Windows.Devices.Geolocation.PositionStatus.NoData:
                    path = "/Assets/close.png";
                    break;
                case Windows.Devices.Geolocation.PositionStatus.NotAvailable:
                    path = "/Assets/close.png";
                    break;
                case Windows.Devices.Geolocation.PositionStatus.NotInitialized:
                    path = "/Assets/questionmark.png";
                    break;
                case Windows.Devices.Geolocation.PositionStatus.Ready:
                    path = "/Assets/check.png";
                    break;
                default:
                    path = "/Assets/close.png";
                    break;
            } 
        }
        else
        {
            path = "/Assets/questionmark.png";
        }

        return path;
    }

在 ViewModel 类中:

public class SignalViewModel : ViewModelBase
{
    private Signalstrength _signalstrength;        

    public Signalstrength Signalstrength
    {
        get { return _signalstrength; }
        set 
        {
            _signalstrength = value;
            Set("Signalstrength", ref _signalstrength, value);
        }
    }
    public SignalViewModel()
    {
            _signalstrength = new Signalstrength
            {
                Imageuri = "/Assets/questionmark.png",
                State = "initializing"
            };

    }
}

型号:

public class Signalstrength : ObservableObject
    {
        private string _state;
        private string _imageuri;        

        public string State
        {
            get { return _state; }
            set 
            {
                _state = value;
                Set("State", ref _state, value);
            }
        }

        public string Imageuri
        {
            get { return _imageuri; }
            set
            {
                _imageuri = value;
                Set("Imageuri", ref _imageuri, value);
            }
        }
    }

当我运行应用程序时,它运行良好,但只有一次。如果我在我的 MainPage 中启动 Geolocator,我看到它找到了我的位置,所以状态必须是 OK,但图像仍然是问号图像,而不是复选标记。

我错过了什么?我怎样才能刷新图像?最后,我尝试实现的方法是否符合 MVVM 要求?

编辑: 我不知道这是否是个问题,但我有 3 个 ViewModel:MainViewModel、WorkoutViewModel 和 SignalViewModel。在我的 MainPage 中,我会这样显示:

<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
            <views:WorkoutView IsHitTestVisible="False" />
        </Grid>
        <Grid Grid.Row="2">
            <views:SignalstrengthView IsHitTestVisible="False" />
        </Grid>

我会在他们的视图中设置 DataContext。 MainViewModel 用于 MainPage,我将其用于 Applicationbar。如果用户点击 AppbarButton,我打开 GPS。因此该代码位于 MainViewModel 中,但显示这些更改的项目位于 SignalViewModel 中。这会是个问题吗?

EDIT2: Geolocator 似乎在后台线程中运行,因此我无法更新 UI。

【问题讨论】:

  • 看起来您缺少一些 INotifyPropertyChanged?
  • 如果需要,我认为 Set() 会自动调用它。
  • 我认为它在更改 Signalstrength 时调用它,而不是它的子属性。因为,您的代码对我来说看起来是正确的。我没有带我的手机来真正测试它。
  • @ChubosaurusSoftware 我尝试手动调用 RaisePropertyChanged,但仍然没有任何反应。
  • 您不需要转换器,只需将转换器逻辑移至视图模型构造函数即可。

标签: c# xaml windows-phone-8 mvvm mvvm-light


【解决方案1】:

这是你的新模型

public class Signalstrength : ObservableObject
    {
        private PositionStatus _state;      

        public PositionStatus State
        {
            get { return _state; }
            set 
            {
                _state = value;
                Set("State", ref _state, value);
            }
        }
    }

在视图模型的构造函数中

_signalstrength = new Signalstrength
            {
                State = Windows.Devices.Geolocation.PositionStatus.Disabled
            };

这是风景

...
DataContext="{Binding Signal, Source={StaticResource Locator}}">
...
<Image Source="{Binding Signalstrength.State, Converter={StaticResource SignalstatusConverter}}" Width="38" Height="38" HorizontalAlignment="Right" Grid.Column="1" />

【讨论】:

  • 在转换器的 else 分支中放置一个断点,在 switch 语句中放置一个断点,也许删除 else 分支。确保在 App.xaml.cs 中初始化 Geolocator,如果它为 null,它将转到 else 分支。它应该看起来像 public Geolocator Geolocator = new Geolocator();
  • 程序在我第一次运行时可以正常运行。问题是当我开始获取我的位置时,程序甚至没有进入转换器代码。
猜你喜欢
  • 1970-01-01
  • 2018-06-06
  • 1970-01-01
  • 2011-08-11
  • 1970-01-01
  • 2020-12-17
  • 2014-08-26
  • 2011-05-11
  • 1970-01-01
相关资源
最近更新 更多