为什么我的数据绑定对PropertyChange没有反应?

时间:2018-08-27 05:16:56

标签: c# .net wpf mvvm data-binding

我试图将DataTrigger绑定到bool属性,但是由于某些原因,它不想更改值。它以false开头,然后当我选择RadioButton时它变为true,但该值不会更新我的DataTrigger。 我尝试绑定TextBox的Text属性,以查看该值是什么,以及它是否改变了但没有改变。 Here is a video showing how it behaves

如您所见,当我调试时,它变为true,但不更新Text属性 当您选择一个项目时,它应该变成false,然后再回到true,因为您选择了一个新的RadioButton。 但是事实并非如此。

主要问题 我正在尝试绑定DataTrigger

<DataTrigger Binding="{Binding Path=EntryItemViewModel.IsEntrySelected}" Value="True">

到我的IsEntrySelected,但是它永远不会将值读为true,除非我在构造函数中明确将其设置为true

public EntryItemViewModel()
        {
            IsEntrySelected = true;
        }

MainWindows.xaml.cs

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        DataContext = new EntryItemListViewModel();
    }
}

和MainWindow.xaml

<Grid>

        <!-- Animation -->
        <Grid.Resources>
            <system:Double x:Key="AddEntrySlideOffset">300</system:Double>
            <Storyboard x:Key="AddEntrySlideRight">
                <DoubleAnimation Storyboard.TargetProperty="(UIElement.RenderTransform).(TranslateTransform.X)"
                                 From="0" To="{StaticResource AddEntrySlideOffset}"
                                 Duration="0:0:0.2" />
            </Storyboard>
            <Storyboard x:Key="AddEntrySlideLeft">
                <DoubleAnimation Storyboard.TargetProperty="(UIElement.RenderTransform).(TranslateTransform.X)"
                                 From="{StaticResource AddEntrySlideOffset}" To="0"
                                 Duration="0:0:0.2" />
            </Storyboard>
        </Grid.Resources>


        <Grid Width="150"
              HorizontalAlignment="Left">
            <local:EntryItemListUserControl x:Name="MyUserControl"/>
        </Grid>

        <TextBox Text="{Binding EntryItemViewModel.IsEntrySelected}"
                 Width="200"
                 Height="25"/>

        <StackPanel Height="50"
                    Width="50"
                    Background="Gainsboro" Margin="375,128,367,241">
            <StackPanel.Style>
                <Style TargetType="StackPanel">
                    <Style.Triggers>
                        <DataTrigger Binding="{Binding Path=EntryItemViewModel.IsEntrySelected}" Value="True">
                            <DataTrigger.EnterActions>
                                <BeginStoryboard Storyboard="{StaticResource AddEntrySlideRight}" />
                            </DataTrigger.EnterActions>
                            <DataTrigger.ExitActions>
                                <BeginStoryboard Storyboard="{StaticResource AddEntrySlideLeft}" />
                            </DataTrigger.ExitActions>
                        </DataTrigger>
                    </Style.Triggers>
                </Style>
            </StackPanel.Style>


            <StackPanel.RenderTransform>
                <TranslateTransform />
            </StackPanel.RenderTransform>
        </StackPanel>

    </Grid>

EntryItemUserControl.xaml

<ListBox HorizontalContentAlignment="Stretch"
             ItemsSource="{Binding Items}"
             SelectedItem="{Binding EntryItem}">
        <ListBox.ItemTemplate>
            <DataTemplate>
                <Grid Margin="0,2">
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="*" />
                    </Grid.ColumnDefinitions>
                    <RadioButton Grid.Column="0"
                                 GroupName="Content"
                                 Content="{Binding Title}"
                                 IsChecked="{Binding IsEntrySelected}"/>
                </Grid>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>

EntryItemListViewModel.cs

public class EntryItemListViewModel : INotifyPropertyChanged
    {
        public ObservableCollection<EntryItemViewModel> Items { get; set; } = new ObservableCollection<EntryItemViewModel>();
        public EntryItemViewModel EntryItemViewModel { get; set; }  = new EntryItemViewModel();

        public EntryItemListViewModel()
        {
            Items.Add(new EntryItemViewModel { Title = "Hello World" });
            Items.Add(new EntryItemViewModel { Title = "Hello World" });
            Items.Add(new EntryItemViewModel { Title = "Hello World" });
            Items.Add(new EntryItemViewModel { Title = "Hello World" });
        }

        private EntryItemViewModel _entryItem;

        public EntryItemViewModel EntryItem
        {
            get { return _entryItem; }
            set
            {
                _entryItem = value;
                OnPropertyChanged(nameof(EntryItem));
            }
        }


        public event PropertyChangedEventHandler PropertyChanged;

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

最后是EntryItemViewModel.cs

public class EntryItemViewModel : INotifyPropertyChanged
    {
        private string _title;

        public string Title
        {
            get { return _title; }
            set
            {
                _title = value;
                OnPropertyChanged("Title");
            }
        }

        private bool _isSelected;

        public bool IsEntrySelected
        {
            get { return _isSelected; }
            set
            {
                _isSelected = value;
                OnPropertyChanged("IsEntrySelected");
            }
        }



        public event PropertyChangedEventHandler PropertyChanged;

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

2 个答案:

答案 0 :(得分:0)

也许这可以帮助您解决问题。

<DataTrigger Binding="{Binding Path=EntryItemViewModel.IsEntrySelected, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Value="True">

答案 1 :(得分:0)

您忘了提及源属性不起作用时如何设置。但是您的EntryItemViewModel中有一个EntryItem属性和另一个EntryItemListViewModel属性。设置IsEntrySelected的{​​{1}}属性应该可以。

您可以通过例如在视图中处理EntryItemViewModel的{​​{1}}来确认这一点:

MouseLeftButtonDown