wpf 属性更新不会触发绑定值更新

j2qf4p5b  于 2022-11-18  发布在  其他
关注(0)|答案(2)|浏览(338)

我花了三天时间试着不问这个问题,因为已经有很多答案了,但没有一个能帮助我到这一刻。
我有一个MainWindow,其中包含TabControlUserControl,我需要将一个属性从MainWindow传递到UserControl,使用下面的代码,它可以工作-UserControl显示“默认值”文本。但是,每当MainWindow上的该属性的值发生变化时,它不会传播到UserControl,也不会触发它的OnSelectedSegmentIdChange,我已经尽了全力,请帮帮我。

主窗口XAML

<Window x:Class="Content_Manager.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
        Title="MainWindow" Height="450" Width="800"
        xmlns:i="http://schemas.microsoft.com/xaml/behaviors" xmlns:usercontrols="clr-namespace:Content_Manager.UserControls"
        x:Name="mainWindow">
        
    <Grid>
      ...
    <ListView x:Name="lvSegments" 
              Grid.Column="0" 
              ItemsSource="{Binding Segments}"
              SelectionMode="Single"
              SelectionChanged="lvSegments_SelectionChanged">
      ...

    <TabControl Grid.Column="1">
        <TabItem Header="О Разделе">
            <usercontrols:SegmentInfoTab SelectedSegmentId="{Binding Path=SegmentId, ElementName=mainWindow}"/>            
    </TabItem>
        ...
    </TabControl>
</Grid>

主窗口C#

public string SegmentId { get; set; } = "Default Value";

public MainWindow()
{
            InitializeComponent();
            DataContext = this;
            ...

    private void lvSegments_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        SegmentId = ((Segment)lvSegments.SelectedItem).Id;
    }
...

用户控件XAML

...
  x:Name="SegmentInfo">
    <Grid>
        <TextBox x:Name="txtName"                 
                 Text="{Binding SelectedSegmentId}"/>
  ...

使用者控件C#

public SegmentInfoTab()
    {
        InitializeComponent();
        DataContext = this;
    }

    public static readonly DependencyProperty SelectedSegmentProperty = DependencyProperty.Register("SelectedSegmentId",
        typeof(string),
        typeof(SegmentInfoTab),
        new PropertyMetadata(string.Empty, OnSelectedSegmentIdChanged));
    
    public string SelectedSegmentId {
        get => (string)GetValue(SelectedSegmentProperty);
        set => SetValue(SelectedSegmentProperty, value);
    }

    private static void OnSelectedSegmentIdChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var newValue= e.NewValue as string;
    }
ymdaylpp

ymdaylpp1#

若要支援自动更新,属性必须通知其变更,或者只能透过系结变更。
在这种情况下,可以实现两个选项:
1.将“MainWindow.SegmentId”属性实作为相依性属性。
1.删除“lvSegments_SelectionChanged”方法并改用绑定:

<ListView x:Name="lvSegments" 
              Grid.Column="0" 
              ItemsSource="{Binding Segments}"
              SelectionMode="Single"
              SelectedValuePath="Id"
              SelectedValue="{Binding Path=SegmentId, ElementName=mainWindow}">

如何做到这一点?SelectedItem不是用来设置值的吗?
如果我没理解错你需要什么:

<ListView x:Name="lvSegments" 
              Grid.Column="0" 
              ItemsSource="{Binding Segments}"
              SelectionMode="Single">
      ...

    <TabControl Grid.Column="1">
        <TabItem Header="О Разделе">
            <usercontrols:SegmentInfoTab
                SelectedSegmentId="{Binding
                                    Path=SelectedItem.SegmentId,
                                    ElementName=lvSegments}"/>            
        </TabItem>
bwitn5fc

bwitn5fc2#

您必须在属性上实作INotifyPropertyChanged。请参阅:How to: Implement Property Change Notification

public class Segment : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    private string _segmentId = "Default Value";
    public string SegmentId
    {
        get { return _segmentId; }
        set
        {
            if (value != _segmentId) {
                _segmentId = value;
                OnPropertyChanged();
            }
        }
    }

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

相关问题