【问题标题】:Why is my Databinding not reacting to a PropertyChange?为什么我的数据绑定对 PropertyChange 没有反应?
【发布时间】:2019-02-01 14:44:09
【问题描述】:

我正在尝试将我的 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));
        }
    }

【问题讨论】:

  • 那么当属性不起作用时,您在哪里设置属性...?

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


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

    您忘记提及在源属性不起作用时如何设置它。但是您的EntryItemListViewModel 中有一个EntryItemViewModel 属性和另一个EntryItem 属性。设置EntryItemViewModelIsEntrySelected 属性应该可以工作。

    您可以通过例如处理视图中的StackPanelMouseLeftButtonDown 来确认这一点:

    private void StackPanel_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
        var vm = DataContext as EntryItemListViewModel;
        vm.EntryItemViewModel.IsEntrySelected = true;
    }
    

    【讨论】:

    • @MarkDenom:你试过这个还是发生了什么?
    猜你喜欢
    • 1970-01-01
    • 2017-01-25
    • 1970-01-01
    • 1970-01-01
    • 2015-12-26
    • 1970-01-01
    • 2013-11-21
    • 2022-01-06
    • 2015-05-29
    相关资源
    最近更新 更多