2016-11-22 30 views
3

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

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没有得到更新?谢谢。

+0

经过进一步的调查,我读的问题可能是绑定必须是单向,因为这不是默认值。当我有一些时间后我会尝试。 – Carlos

回答

2

一个错误大多数人(包括我自己)经常做时使用的“老” Binding语法是x:BindOneTime为默认值,而不是OneWay结合结合。

模式:指定装订模式时,这些字符串中的一个:“一次性”,“单向”或“双向”。默认值是“OneTime”。请注意,这与{Binding}在大多数情况下是“OneWay”的默认值不同。

来源:MSDN

你需要为你绑定更新工作是什么:

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

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

+0

感谢您的帮助。现在更新主要属性的工作,尽管如果我更改ObservableCollections的其中一个元素内的东西,它不会更新UI。我有的结构是:房间(属性+执行器ObservableColletion)=>执行器(属性+执行器状态ObservableColletion)。虽然我已经在Actuator和ActuatorStatus模型中实现了BindableBase,但UI并未更新。所有绑定现在都是单向的。 – Carlos

+0

出于某种原因,在ListView中,使用“{x:Bind xxx,Mode = OneWay}”不会让UI得到更新,但“{Binding xxx,Mode = OneWay}”完美地工作。再次感谢你的帮助。 – Carlos

+0

@Carlos你可以重新表示x:绑定行为吗?如果可以的话,可靠地给我一个链接到repro项目,我会告诉团队。如果可以,请在Microsoft.com上给我发电子邮件@ Jerry.Nixon。 –