2017-09-20 3 views
1

내 프로젝트에 XAML보기 및보기 모델이 있습니다. 프로젝트는 스톱워치이며 Lap 버튼을 누를 때 ObservableCollection에 객체가 추가됩니다. ObservableCollection은 뷰에 ListView로 표시됩니다.Xamarin 단추 명령이 실행되지 않는다

ListView에서 컬렉션 항목 중 하나를 삭제하는 버튼이 추가되었습니다. 그것에는 "DeleteTimingCommand"라는 바인딩과 "Collection"에서 객체를 삭제하기 위해 사용하고자하는 식별자 인 "Position"이라는 Binding을 가진 CommandParameter가있는 명령이 있습니다.

DeleteTimingCommand는 ViewModel 생성자에 있으며 "DeleteTiming"이라는 메서드를 시작하도록 설정되어 있습니다. 이 메소드는 실제 삭제를 처리합니다.

그러나 내 코드가 내 DeleteTiming() 메서드에 전혀 충돌하지 않습니다! 중단 점을 어디에 두든 상관없이 아무 것도 발생하지 않습니다. 버튼을 누르면 아무 일도 일어나지 않습니다.

뭔가가 제대로 연결되지 않습니다. 누구든지 올바른 방향으로 나를 가리킬 수 있습니까?

XAML

<?xml version="1.0" encoding="UTF-8"?> 
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" 
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" 
    x:Class="TechsportiseApp.Views.Timer" Title="Timer"> 
    <StackLayout VerticalOptions="Start" HorizontalOptions="FillAndExpand"> 
     <StackLayout Orientation="Horizontal"> 
      <Label Text="{Binding ElapsedTime}" HorizontalOptions="FillAndExpand" HorizontalTextAlignment="Center" FontSize="40"/> 
      <Button Command="{Binding LapCommand}" BackgroundColor="#eca400" IsVisible="{Binding EndVisibility}" Image="Scanning.png" WidthRequest="50" HeightRequest="50"/> 
     </StackLayout> 
     <Button x:Name="buttonStart" Text="Start Race" Command="{Binding StartTimerCommand}" IsVisible="{Binding StartVisibility}" /> 
     <Button x:Name="buttonEnd" Text="End Race" Command="{Binding EndTimerCommand}" IsVisible="{Binding EndVisibility}" /> 
     <Button x:Name="buttonSubmit" Text="Submit Results" Command="{Binding EndTimerCommand}" IsVisible="{Binding SubmitVisibility}" /> 
     <BoxView HeightRequest="1" Color="Silver" HorizontalOptions="FillAndExpand" /> 
     <Label Text="YOUR RESULTS" HorizontalOptions="FillAndExpand" HorizontalTextAlignment="Center" FontSize="Small" FontAttributes="Bold"/> 
     <BoxView HeightRequest="1" Color="Silver" HorizontalOptions="FillAndExpand" /> 

     <ListView ItemsSource="{Binding Timings}" 
     SeparatorVisibility="None" 
     HasUnevenRows="true"> 
      <ListView.ItemTemplate> 
       <DataTemplate> 
        <ViewCell> 
         <Grid RowSpacing="3" ColumnSpacing="3"> 
          <Grid.RowDefinitions> 
           <RowDefinition Height="Auto" /> 
           <RowDefinition Height="Auto" /> 
          </Grid.RowDefinitions> 
          <Grid.ColumnDefinitions> 
           <ColumnDefinition Width="50" /> 
           <ColumnDefinition Width="*" /> 
           <ColumnDefinition Width="50" /> 
          </Grid.ColumnDefinitions> 
          <Label x:Name="Pos" Text="{Binding Position}" VerticalTextAlignment="Center" HorizontalTextAlignment="Center" Grid.Row="0" Grid.Column="0" FontSize="Large" FontAttributes="Bold"/> 
          <Label Text="{Binding Elapsed}" VerticalTextAlignment="Center" Grid.Row="0" Grid.Column="1" FontSize="Large" /> 
          <Button Image="trash.png" BackgroundColor="Red" WidthRequest="50" HeightRequest="50" Command="{Binding DeleteTimingCommand}" CommandParameter="{Binding Position}" Grid.Row="0" Grid.Column="2" /> 
          <BoxView HeightRequest="1" Color="Silver" HorizontalOptions="FillAndExpand" Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="3" /> 

         </Grid> 
        </ViewCell> 
       </DataTemplate> 
      </ListView.ItemTemplate> 
     </ListView> 
    </StackLayout> 
</ContentPage> 

뷰 모델

using System; 
using System.Collections.Generic; 
using System.Collections.ObjectModel; 
using System.ComponentModel; 
using System.Diagnostics; 
using System.Linq; 
using System.Timers; 
using System.Windows.Input; 
using TechsportiseApp.Models; 
using Xamarin.Forms; 

namespace TechsportiseApp.ViewModels 
{ 
    public class TimerViewModel : INotifyPropertyChanged 
    { 
     public Timer myTimer = new Timer(); 

     public ICommand StartTimerCommand { get; set; } 
     public ICommand EndTimerCommand { get; set; } 
     public ICommand LapCommand { get; set; } 
     public ICommand DeleteTimingCommand { get; set; } 

     public TimerViewModel() 
     { 
      StartTimerCommand = new Command(StartTimer); 
      EndTimerCommand = new Command(EndTimer); 
      LapCommand = new Command(LapButton); 
      DeleteTimingCommand = new Command<int>(DeleteTiming); 
      Timings = new ObservableCollection<Timing>(); 
      LapPosition = 1; 
      StartVisibility = true; 
      EndVisibility = false; 
      SubmitVisibility = false; 
     } 


     //TimeSpan _elapsedTime; 
     //public TimeSpan ElapsedTime 
     //{ 
     // get {    
     //  return _elapsedTime; 
     // } 
     // set 
     // { 
     //  if (_elapsedTime == value) 
     //   return; 

     //  _elapsedTime = value; 
     //  OnPropertyChanged("ElapsedTime"); 
     // } 
     //} 

     string _elapsedTime; 
     public String ElapsedTime 
     { 
      get 
      { 
       if (_elapsedTime != null) 
       { 
        return _elapsedTime; 
       } 
       else 
       { 
        _elapsedTime = "00:00:00.00"; 
        return _elapsedTime; 
       } 

      } 
      set 
      { 
       if (_elapsedTime == value) 
        return; 

       _elapsedTime = value; 
       OnPropertyChanged("ElapsedTime"); 
      } 
     } 

     DateTime _currentTime; 
     public DateTime CurrentTime 
     { 
      get { return _currentTime; } 
      set 
      { 
       if (_currentTime == value) 
        return; 

       _currentTime = value; 
       OnPropertyChanged("CurrentTime"); 
      } 
     } 

     bool _startVisibility; 
     public bool StartVisibility 
     { 
      get { return _startVisibility; } 
      set 
      { 
       if (_startVisibility == value) 
        return; 

       _startVisibility = value; 
       OnPropertyChanged("StartVisibility"); 
      } 
     } 

     bool _endVisibility; 
     public bool EndVisibility 
     { 
      get { return _endVisibility; } 
      set 
      { 
       if (_endVisibility == value) 
        return; 

       _endVisibility = value; 
       OnPropertyChanged("EndVisibility"); 
      } 
     } 

     bool _submitVisibility; 
     public bool SubmitVisibility 
     { 
      get { return _submitVisibility; } 
      set 
      { 
       if (_submitVisibility == value) 
        return; 

       _submitVisibility = value; 
       OnPropertyChanged("SubmitVisibility"); 
      } 
     } 

     DateTime _raceStartTime; 
     public DateTime RaceStartTime 
     { 
      get { return _raceStartTime; } 
      set 
      { 
       if (_raceStartTime == value) 
        return; 

       _raceStartTime = value; 
       OnPropertyChanged("RaceStartTime"); 
      } 
     } 

     DateTime _lapTime; 
     public DateTime LapTime 
     { 
      get { return _lapTime; } 
      set 
      { 
       if (_lapTime == value) 
        return; 

       _lapTime = value; 
       OnPropertyChanged("LapTime"); 
      } 
     } 

     ObservableCollection<Timing> _timings; 
     public ObservableCollection<Timing> Timings 
     { 
      get 
      { 
       //var sortedtimings = new ObservableCollection<Timing>(_timings.OrderBy(c => c.Position)); 
       var sortedtimings = new ObservableCollection<Timing>(_timings.OrderByDescending(c => c.Position)); 
       _timings = sortedtimings; 
       return _timings; 
      } 
      set 
      { 
       if (_timings != value) 
       { 
        _timings = value; 
        OnPropertyChanged("Timings"); 
       } 
      } 
     } 

     int _lapPosition; 
     public int LapPosition 
     { 
      get { return _lapPosition; } 
      set 
      { 
       if (_lapPosition == value) 
        return; 

       _lapPosition = value; 
       OnPropertyChanged("LapPosition"); 
      } 
     } 



     public event PropertyChangedEventHandler PropertyChanged; 

     protected virtual void OnPropertyChanged(string propertyName) 
     { 
      var changed = PropertyChanged; 
      if (changed != null) 
      { 
       PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
      } 
     } 

     void StartTimer() 
     { 
      RaceStartTime = DateTime.Now; 
      myTimer.Elapsed += new ElapsedEventHandler(DisplayTimeEvent); 
      myTimer.Interval = 10; // 1000 ms is one second 
      myTimer.Start(); 
      StartVisibility = false; 
      EndVisibility = true; 
      //ElapsedTime = myTimer.Elapsed.Milliseconds() += new ElapsedEventHandler(DisplayTimeEvent); 
     } 

     void EndTimer() 
     { 
      myTimer.Stop(); 
      EndVisibility = false; 
      SubmitVisibility = true; 
      //ElapsedTime = myTimer.Elapsed.Milliseconds() += new ElapsedEventHandler(DisplayTimeEvent); 
     } 

     void DisplayTimeEvent(object source, ElapsedEventArgs e) 
     { 
      TimeSpan _elapsed; 
      _elapsed = e.SignalTime - RaceStartTime; 

      string hours = _elapsed.Hours.ToString().PadLeft(2, '0'); 
      string minutes = _elapsed.Minutes.ToString().PadLeft(2, '0'); 
      string seconds = _elapsed.Seconds.ToString().PadLeft(2, '0'); 
      int _hundredths = _elapsed.Milliseconds/10; 

      string hundredths = _hundredths.ToString().PadLeft(2, '0'); 
      _elapsedTime = hours + ":" + minutes + ":" + seconds + "." + hundredths; 
      ElapsedTime = _elapsedTime; 
      OnPropertyChanged("ElapsedTime"); 
     } 

     void LapButton() 
     { 
      var lap = new Timing 
      { 
       Id = 0, 
       RaceId = 0, 
       StartTime = RaceStartTime, 
       EndTime = DateTime.Now, 
       Elapsed = ElapsedTime, 
       Position = LapPosition, 
       Status = 0 
      }; 
      Timings.Add(lap); 

      OnPropertyChanged("Timings"); 
      LapPosition = LapPosition + 1; 
      var listcheck = Timings.Count; 

     } 

     void DeleteTiming(int position) 
     { 
      foreach (var timing in Timings) 
      { 
       if (timing.Position == position) 
       { 
        Timings.Remove(timing);     
        break; 
       } 
      } 

      var NewPosition = Timings.Count(); 
      foreach (var timing in Timings) 
      { 
       timing.Position = NewPosition; 
       NewPosition = NewPosition - 1; 
      } 

      OnPropertyChanged("Timings"); 
     } 
    } 
} 
+0

목록의 각 요소는 Timing 개체에 바인딩되며 TimerViewModel 클래스에 명령이 정의되어 있습니다 – Jason

답변

2

현재 코드에 따라 경찰, 양식 프레임 워크는 해당 Timing 객체 DeleteTimingCommand을 찾기 위해 노력할 것입니다. 이 문제를 해결하기 위해 부모 뷰 모델을 바인딩의 소스로 지정해야합니다. 부모 요소에

추가 이름 참조 속성 :

<ContentPage x:Name="ParentView" xmlns="http://xamarin.com/sch .. 

그리고, 당신은 바인딩 변경 : 양식 프레임 워크는 학부모의 명령에 대해보고 알 수

<Button Image="trash.png".. Command="{Binding BindingContext.DeleteTimingCommand, Source={x:Reference ParentView}}" CommandParameter="{Binding Position}" .. /> 

이 방법 보기의보기 모델 (예 : TimerViewModel).

관련 문제