Как связать массив значений bool с видимостью их соответствующего эллипса в коде cs? - PullRequest
0 голосов
/ 04 июня 2018

Я пишу программу uwp, в которой я хочу связать ObservableCollection с видимостью эллипса в матрице эллипса.Поскольку я хочу сделать число эллипсов гибким, я инициализирую и связываю их в коде инициализации c # страницы.Проблема в том, что видимости эллипсов отражают значения bool, которые я установил до того, как произошло связывание, но когда значение bool изменяется после привязки, видимости не меняются при изменении значения bool.

Я объявляю boolзначения в App.xaml.cs

public int gameRow;`enter code here`
public int gameColumn;
public ObservableCollection<bool> gameMatrix;

На странице эллипсов я объявляю сетку для хранения эллипсов в GamePage.xaml.

<Grid Grid.Column="1" Grid.Row="0"  x:Name="gameFlat"/>

в соответствующей GamePage.xaml.cs, я инициализировал эллипсы, связал их со значениями bool и поместил их в строку / столбец в сетке gameFlat.

private void addEllipse(int i, int j, Binding[,] ellipseBindings)
{
      ellipseBindings[i,j] = new Binding();
      ellipseBindings[i, j].Source = gameMatrix[i*gameColumn+ j];
      if (converter==null)
           converter = new VisibilityConverter();
      ellipseBindings[i, j].Converter = converter;
      circles[i, j] = new Ellipse();
      SolidColorBrush mySolidColorBrush = new SolidColorBrush();
      mySolidColorBrush.Color = Windows.UI.Color.FromArgb(255, 255, 106, 106);
      circles[i, j].Fill = mySolidColorBrush;
      circles[i, j].SetBinding(VisibilityProperty, ellipseBindings[i, j]);
      Grid.SetRow(circles[i, j], i);
      Grid.SetColumn(circles[i, j], j);
      gameFlat.Children.Add(circles[i, j]);
}

Круги и ellipseBinds объявлены в GamePage.xaml.cs также.

Ellipse[,] circles;
Binding[,] EllipseBindings;
VisibilityConverter converter;

Видимость эллипсов контролируется значениями bool в первый раз, но когда я пытаюсь изменить значение bool после привязки, в функции отметки времени таймераизменение значений bool не влияет на эллипсы.

private void timer_tick(object sender, object e)
{
    int testCount = pkgCountDown % (gameRow * gameColumn);
    gameMatrix[(testCount % gameRow)* gameColumn
       + pkgCountDown% gameColumn ] = true;
    gameCountDown--;
    pkgCountDown--;
} 

Что не так в моем коде?Не могли бы вы помочь мне заставить это работать?Спасибо!

------- обновление 2018/06/07 --------

Я попытался обернуть значения bool в класс isShownNotify, который реализуетинтерфейс INotifyPropertyChanged, как показано ниже:

public class isShownNotify : INotifyPropertyChanged
{
     public event PropertyChangedEventHandler PropertyChanged;
     private bool _isShown;
     public bool isShown
     {
           get { return _isShown; }
           set
           {
               if (_isShown != value)
               {
                    isShown = value;               
               }
               OnPropertyChanged();
            }
     }
     public void OnPropertyChanged([System.Runtime.CompilerServices.CallerMemberName] string name = "")
     {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler!=null)
            handler(this, new PropertyChangedEventArgs(name));
     }
}

Затем я изменил конвертер, как показано ниже:

object IValueConverter.Convert(object value, Type targetType, object parameter, string language)
{
    Type objectType = value.GetType();
    PropertyInfo objectInfo = objectType.GetProperty("isShown");
    bool boolValue = (bool)objectInfo.GetValue(value, null);
    if (boolValue == true)
        return Visibility.Visible;
    else
        return Visibility.Collapsed;
}

Но при запуске программы изменения значений bool по-прежнему не меняютсявидимость моих эллипсов.

Когда я устанавливаю точки останова в функции OnPropertyChanged (), я вижу, что значение PropertyChanged (PropertyChangedEventHandler) равно нулю.Что с этим не так?Должен ли я неправильно связать это с видимостью эллипсов?

1 Ответ

0 голосов
/ 12 июня 2018

@ MD Музибур Рахман был прав.Вам нужно определить собственный класс и реализовать для него интерфейс INotifyPropertyChanged.Я видел, что ты это сделал.Замечательно.Но вы сказали, что это не работает.После проверки вашего кода проблема возникла из-за того, что вы хотите динамически изменять значение свойства, но вы не привязаны к своему свойству в привязке, например binding.Path = new PropertyPath("IsShown");.Вот почему это не работает для вас.

Я сделал простой пример кода для вашей справки:

<StackPanel>
    <Grid Grid.Column="1" Grid.Row="0"  x:Name="gameFlat">
    </Grid>
    <Button Content="add" Click="Button_Click"></Button>
    <Button Content="Hide" Click="Button_Click_1"></Button>
</StackPanel>
public ObservableCollection<gameMatrix> gameMatrixlist;
Binding binding;
Ellipse ellipse;
private void addEllipse()
{
    gameMatrixlist = new ObservableCollection<gameMatrix>() { new gameMatrix() {IsShown = true } };

    binding = new Binding();
    binding.Source = gameMatrixlist[0];
    binding.Path = new PropertyPath("IsShown");
    binding.Converter = new VisibilityConverter();

    ellipse = new Ellipse();
    SolidColorBrush mySolidColorBrush = new SolidColorBrush();
    mySolidColorBrush.Color = Windows.UI.Color.FromArgb(255, 255, 106, 106);
    ellipse.Fill = mySolidColorBrush;
    ellipse.Height = 100;
    ellipse.Width = 100;
    ellipse.SetBinding(VisibilityProperty, binding);

    Grid.SetRow(ellipse, 0);
    Grid.SetColumn(ellipse, 0);
    gameFlat.Children.Add(ellipse);
}

private void Button_Click(object sender, RoutedEventArgs e)
{
    addEllipse();
}

private void Button_Click_1(object sender, RoutedEventArgs e)
{
    gameMatrixlist[0].IsShown = false;
}

public class gameMatrix : INotifyPropertyChanged
{
    private bool _IsShown;
    public bool IsShown
    {
        get { return _IsShown; }
        set
        {
            if (value == _IsShown) return;
            _IsShown = value;
            OnPropertyChanged("IsShown");
        }
    }


    public event PropertyChangedEventHandler PropertyChanged;
    protected virtual void OnPropertyChanged(string propertyName = null)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
    }
}
public class VisibilityConverter:IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, string language)
    {
        if (value != null)
        {
            bool boolValue =  (bool)value;
            if (boolValue == true)
                return Visibility.Visible;
            else
                return Visibility.Collapsed;
        }
        return Visibility.Collapsed;


    }

    public object ConvertBack(object value, Type targetType, object parameter, string language)
    {
        return Visibility.Collapsed;
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...