属性更改后,Template10 UI未刷新

时间:2016-11-22 21:49:16

标签: c# mvvm uwp template10

我正在使用模板10处理UWP应用程序,并且我无法在ViewModel中更改属性后更新UI。我试图在模型中实现Bindable基础,但仍然不起作用。

XAML:

<Page.DataContext>
    <vm:RoomPageViewModel x:Name="ViewModel" />
</Page.DataContext>

<Grid x:Name="RoomProperties"
    RelativePanel.Below="pageHeader"
    RelativePanel.AlignLeftWithPanel="True">
    <Grid.ColumnDefinitions>
        <ColumnDefinition></ColumnDefinition>
        <ColumnDefinition></ColumnDefinition>
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
        <RowDefinition></RowDefinition>
        <RowDefinition></RowDefinition>
        <RowDefinition></RowDefinition>
    </Grid.RowDefinitions>
    <Image Grid.Column="0" Width="220" Height="220" Stretch="Fill" Source="{x:Bind ViewModel.Room.Image}"></Image>
    <TextBlock Grid.Column="1" FontSize="16" Text="{x:Bind ViewModel.Room.Name}"></TextBlock>
    <TextBlock Grid.Column="0" Grid.Row="1" FontSize="16" Text="Room Type: "></TextBlock>
    <TextBlock Grid.Column="1" Grid.Row="1" FontSize="16" Text="{x:Bind ViewModel.Room.Type}"></TextBlock>
    <TextBlock Grid.Column="0" Grid.Row="2" FontSize="16" Text="Room Number: "></TextBlock>
    <TextBlock Grid.Column="1" Grid.Row="2" FontSize="16" Text="{x:Bind ViewModel.Room.Number}"></TextBlock>
</Grid>
<ListView x:Name="SensorListView"
          ItemsSource="{x:Bind ViewModel.Room.Sensors}"
          IsEnabled="False"
          RelativePanel.Below="RoomProperties"
          RelativePanel.AlignLeftWithPanel="True">
    <ListView.ItemTemplate>
        <DataTemplate x:DataType="data:Sensor">
            <StackPanel HorizontalAlignment="Left">
                <Grid>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition></ColumnDefinition>
                        <ColumnDefinition></ColumnDefinition>
                        <ColumnDefinition></ColumnDefinition>
                    </Grid.ColumnDefinitions>
                    <TextBlock Grid.Column="0" FontSize="16" Text="{x:Bind Name}"></TextBlock>
                    <TextBlock Grid.Column="1" FontSize="16" Text="{x:Bind SensorValues[0].Value, Mode=TwoWay}"></TextBlock>
                    <TextBlock Grid.Column="2" FontSize="16" Text="{x:Bind Units}"></TextBlock>
                </Grid>
            </StackPanel>
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

视图模型:

public class RoomPageViewModel : ViewModelBase
{
    Template10.Services.SerializationService.ISerializationService _SerializationService;
    private FileIOHelper.FileIOHelper fileIOHelper = new FileIOHelper.FileIOHelper();
    private AppServiceConnection serialCommandService;

    // This method is called by the Set accessor of each property.
    // The CallerMemberName attribute that is applied to the optional propertyName
    // parameter causes the property name of the caller to be substituted as an argument.

    public RoomPageViewModel()
    {
        if (Windows.ApplicationModel.DesignMode.DesignModeEnabled)
        {
            Room = Room.CreateNewRoom();
        }
    }

    private Room room = Room.CreateNewRoom();
    public Room Room
    {
        get
        {
            return this.room;
        }

        set
        {
            Set(ref room, value);
        }
    }

    public void UpdateRoom()
    {
        foreach (var sensor in Room.Sensors)
        {
            var sensorValue = new SensorValue();
            sensorValue.Sensor = "R" + Room.Number + "D" + sensor.DeviceNumber + "S" + sensor.Type;
            ObservableCollection<SensorValue> newList = fileIOHelper.ReadFromFile(sensorValue).ToObservableCollection();
            SensorValue newSensorValue = newList.Last();
            sensor.SensorValues = new ObservableCollection<SensorValue> { newSensorValue };
        }
        foreach (var actuator in Room.Actuators)
        {
            var actuatorValue = ActuatorValue.CreateNewActuatorValue();
            actuatorValue.Actuator = "R" + Room.Number + "D" + actuator.DeviceNumber + "A" + actuator.Type;
            ObservableCollection<ActuatorValue> newList = fileIOHelper.ReadFromFile(actuatorValue).ToObservableCollection();
            ActuatorValue newActuatorValue = newList.Last();
            actuator.ActuatorValues = new ObservableCollection<ActuatorValue> { newActuatorValue };
        }
    }

    public async void RefreshButton_Click(object sender, object parameter)
    {
        Random rnd = new Random();
        Room = Room.CreateNewRoom(rnd.Next(1, 9));
        //UpdateRoom();
        await Task.CompletedTask;
    }

型号:

public class Room : BindableBase
{
    private string name;
    private string image;
    private string type;
    private int number; 

    public string Name
    {
        get
        {
            return name;
        }
        set
        {
            Set(ref name, value);
        }
    }

    public string Image
    {
        get
        {
            return image;
        }
        set
        {
            Set(ref image, value);
        }
    }

    public string Type
    {
        get
        {
            return type;
        }
        set
        {
            Set(ref type, value);
        }
    }

    public int Number
    {
        get
        {
            return number;
        }
        set
        {
            Set(ref number, value);
        }
    }

    private ObservableCollection<Sensor> sensors;

    private ObservableCollection<Actuator> actuators;

    public ObservableCollection<Sensor> Sensors
    {
        get
        {
            return sensors;
        }
        set
        {
            Set(ref sensors, value);
        }
    }

    public ObservableCollection<Actuator> Actuators
    {
        get
        {
            return actuators;
        }
        set
        {
            Set(ref actuators, value);
        }
    }

    public Room() {
        Random rnd = new Random();
        Name = "DefaultName";
        Image = "DefaultImage";
        Type = "DefaultType";
        Number = rnd.Next(1,9);
        Sensors = new ObservableCollection<Sensor>();
        Actuators = new ObservableCollection<Actuator>();
    }

    public Room(int inputNumber)
    {
        Name = "DefaultName";
        Image = "DefaultImage";
        Type = "DefaultType";
        Number = inputNumber;
        Sensors = new ObservableCollection<Sensor>();
        Actuators = new ObservableCollection<Actuator>();
    }

    public static Room CreateNewRoom(int inputNumber)
    {
        return new Room(inputNumber);
    }
}

我将本指南用于实施文档(https://github.com/Windows-XAML/Template10/wiki/MVVM)。关于为什么UI没有得到更新的任何想法?感谢。

1 个答案:

答案 0 :(得分:2)

大多数人(包括我自己)在习惯使用'旧'Binding语法时经常犯的错误是x:BindOneTime绑定为默认值而不是OneWay结合。

  

模式:指定绑定模式,作为以下字符串之一:“OneTime”,“OneWay”或“TwoWay”。默认为“OneTime”。请注意,这与{Binding}的默认值不同,在大多数情况下为“OneWay”。

来源:MSDN

您的绑定更新工作所需的是:

  • 使用INotifyPropertyChanged,由BindableBase处理。
  • 设置正确的模式,例如

    Text="{x:Bind ViewModel.Room.Number, Mode=OneWay}