Как правильно связать свойство Checkbox - PullRequest
0 голосов
/ 07 января 2019

Я работаю над wpf-приложением и сейчас имею дело с флажками Проблема, когда я установил для свойства Ischecked значение «True», например:

   <CheckBox  Visibility="{Binding checkVisibility}" IsChecked="true" 
   IsEnabled="True"></CheckBox>

Я поставил галочку Но когда я пытаюсь связать булево свойство, которое имеет значение "true", я всегда проверяю флажок Я не вижу, где находится проплэм

это мой xaml

 <CheckBox  Visibility="{Binding checkVisibility}" IsChecked="{Binding Path=test,UpdateSourceTrigger=PropertyChanged,Mode=TwoWay}" IsEnabled="True"></CheckBox>

это моя собственность

public bool _test = true;

public bool test {
    get {
        return _test;
    }
    set {
        if (_test == value) {
            return;
        }

        _test = value;
        RaisePropertyChanged("test");
    }
}

Я хочу, чтобы мой флажок отражал значение моего свойства, и наоборот, но это не тот случай, так как мой флажок всегда снят Я что-то упустил?

Редактировать Вот моя ВМ:

namespace X{
public class MyViewModel :  
{ 
public MyViewModel()
{
  TestCheckbox();
}
#Region Properties

    public bool _test1 = true;
    public bool test1
    {
        get
        {
            return _test1;
        }

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

            _test1 = value;
            RaisePropertyChanged("test1");
        }
    }

 ObservableCollection<Output> _output_List;
    public ObservableCollection<Output> output_List
    {
        get { return _output_List; }
        set
        {
            if (_output_List == value) return;
            _output_List = value;
            RaisePropertyChanged("output_List");
        }

    }
#EndRegion
#Region ButtonCommand
  private RelayCommand _SetOutputPropertiesCommand;

    public RelayCommand SetOutputPropertiesCommand => _SetOutputPropertiesCommand
                ?? (_SetOutputPropertiesCommand = new RelayCommand(
                () =>
                {   
                        foreach (Output item in output_List)
                        {
                          item.myvalue=Test2;
                        }
                    }

                }));

#EndRegion
#Region Method
  public void TestCheckbox()
    {
     Console.Writeline(Test2);
    }
#EndRegion    

            }
  public class Output
{
    public string label { get; set; }
    public string type { get; set; }
    public bool myvalue { get; set; }
    public bool Test2 { get; set; }
    [System.ComponentModel.DataAnnotations.Schema.NotMapped]
    [JsonIgnore]
    public string checkVisibility { get; set; }
}
}

Мой Xaml: мои флажки интегрированы в представление DataGrid

                    <DataGrid x:Name ="GridO"  Style="{x:Null}"
                    ItemsSource= "{Binding output_List,UpdateSourceTrigger=PropertyChanged}"

                  AutoGenerateColumns="False" CellStyle="{StaticResource Body_Content_DataGrid_Centering}"
                  Margin="5,0" IsReadOnly="True" SelectionMode="Single" RowHeight="50" Height="Auto">


                        <DataGrid.Columns>

                            <DataGridTextColumn Width="40*" Binding="{Binding label}">
                                <DataGridTextColumn.HeaderTemplate>
                                    <DataTemplate>
                                        <TextBlock  Text="Input"></TextBlock>
                                    </DataTemplate>
                                </DataGridTextColumn.HeaderTemplate>
                            </DataGridTextColumn>

                            <DataGridTextColumn  Width="40*" Binding="{Binding type}">
                                <DataGridTextColumn.HeaderTemplate>
                                    <DataTemplate>
                                        <TextBlock  Text = "Type"></TextBlock>
                                    </DataTemplate>
                                </DataGridTextColumn.HeaderTemplate>
                            </DataGridTextColumn>


                            <DataGridTemplateColumn Width="20*" >
                                <DataGridTemplateColumn.Header>
                                    <TextBlock Text="Value" />
                                </DataGridTemplateColumn.Header>
                                <DataGridTemplateColumn.CellTemplate>
                                    <DataTemplate>
                                            <CheckBox Margin="20,0,0,0" Visibility="{Binding checkVisibility }" IsChecked="{Binding Test2,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" IsEnabled="True"></CheckBox>
                                    </DataTemplate>
                                </DataGridTemplateColumn.CellTemplate>
                            </DataGridTemplateColumn>

                        </DataGrid.Columns>
                    </DataGrid>
   <Button x:Name="Valid_output" Cursor="Hand" Background="Transparent"  Height="55"  Width="140" Margin="0,0,20,0" Command="{Binding SetOutputPropertiesCommand}"  >

Привязка работает с «Test2» и не работает с «Test1», который не относится к тому же классу, что и Test2 NB: Команда Button (которая находится в том же классе, что и «Test1») работает хорошо

Мой DataTemplate: есть в App.xaml

  xmlns:v="clr-namespace:X.View"
  xmlns:vm="clr-namespace:X"
   <DataTemplate DataType="{x:Type vm:MyViewModel}">
            <v:MyWindow/>

Ответы [ 2 ]

0 голосов
/ 08 января 2019

Я вижу главную проблему в DataGrid. Вы устанавливаете ItemsSource в коллекцию, поэтому для каждой строки в DataGrid источником данных является один элемент в этой коллекции. Не твой MyViewModel.

Это причина, по которой Test2 работает - именно в классе экземпляры находятся в коллекции.

Вы можете попытаться добавить CheckBox в окно без DataGrid и связать Test1 - оно должно работать.

Если вы действительно хотите использовать какое-то свойство из вашего MyViewModel, вы можете, но это не так просто. Вы должны иметь что-то вроде:

xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:YourNamespace"

<!--...something...-->

<DataGrid.Resources>
   <local:BindingProxy x:Key="Proxy" Data="{Binding}" />
</DataGrid.Resources>

<!--...something...-->

И тогда ваша привязка в DataGrid будет выглядеть так:

IsChecked="{Binding Data.Test1, Source={StaticResource Proxy}}"

Конечно, я не знаю точных настроек вашего приложения, поэтому вам придется заполнить / изменить код в соответствии с ними.

0 голосов
/ 07 января 2019

Я предлагаю вам добавить класс ViewModelBase, например

public abstract class ViewModelBase : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = 
    null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

Расширяет вашу ViewModel с помощью этого класса ViewModelBase и реализует ваше свойство

private bool myProperty;

public bool MyProperty { get; set; OnPropertyChanged(); }

Тогда вам просто нужно связать свою собственность

<CheckBox IsChecked="{Binding MyProperty}"></CheckBox>

РЕДАКТИРОВАТЬ: Чтобы установить вашу ViewModel в качестве DataContext для вашего просмотра, вы можете установить его из кода

MyView.DataContext = new MyViewModel();

или из вида, в окне / Элемент управления пользователя

<Window x:Class="MyApplication.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:MyApplication"
    Title="MainWindow" Height="350" Width="525"
    DataContext="local.MyViewModel">
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...