数据绑定到对象的KVP,对象不允许实时使用或更新属性

本文关键字:对象 更新 属性 实时 不允许 KVP 数据绑定 | 更新日期: 2023-09-27 18:15:14

我有用于构建列表的操作类和结果类,我使用xaml绑定到属性,并使用转换器根据某些属性返回一些内容,大部分工作....

为了方便起见,我将发布xaml,然后注意什么是有效的,我需要什么帮助。

<UserControl x:Class="OperationListView"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"   
         xmlns:telerik="http://schemas.telerik.com/2008/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         mc:Ignorable="d" 
         xmlns:prism="http://www.codeplex.com/prism"
         xmlns:inf="clr-namespace:***;assembly=***"
         xmlns:c="clr-namespace:****.***"
         d:DesignHeight="300" d:DesignWidth="300">
<Control.Resources>
    <c:LanguageTextConverter x:Key="langConverter" />
    <c:ResultViewConverter x:Key="statusConverter" />
    <c:OpDetailViewConverter x:Key="opConverter" />
</Control.Resources>
<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="1*"/>
    </Grid.ColumnDefinitions>
    <telerik:RadGridView Name="OperationGrid"
                         Grid.Column="0"
                         RowHeight="75"
                         SelectionMode="Single"
                         SelectedItem="{Binding SelectedOperation, Mode=TwoWay}"
                         ItemsSource="{Binding Operations}"
                         IsReadOnly="True"
                         AutoGenerateColumns="False"
                         RowDetailsVisibilityMode="VisibleWhenSelected"
                         ShowGroupPanel="False"
                         RowIndicatorVisibility="Collapsed" >
        <telerik:RadGridView.RowDetailsTemplate>
            <DataTemplate>
                <ContentControl Grid.Column="1" Template="{Binding Converter={StaticResource opConverter}}" />
            </DataTemplate>
        </telerik:RadGridView.RowDetailsTemplate>
        <telerik:RadGridView.Columns>
            <telerik:GridViewDataColumn Header="Name"
                                        DataMemberBinding="{Binding Key.operationName, Converter={StaticResource langConverter}}"
                                        Width="2*"
                                        IsGroupable="False" />
            <telerik:GridViewDataColumn Header="Result"
                                        Width="1*"
                                        MaxWidth="75"> 
                <telerik:GridViewDataColumn.CellTemplate>
                    <DataTemplate>
                        <Grid>
                            <ContentControl Template="{Binding Value, Converter={StaticResource statusConverter}}"/>
                        </Grid>
                    </DataTemplate>
                </telerik:GridViewDataColumn.CellTemplate>
            </telerik:GridViewDataColumn>
        </telerik:RadGridView.Columns> 
    </telerik:RadGridView>
</Grid>

在最终绑定之前的所有内容都有效,甚至最终绑定也有效到某一点…

<ContentControl Template="{Binding Value, Converter={StaticResource statusConverter}}"/>   

当绑定到Value时,转换器会在加载时触发并加载相应的xaml。

然而,没有其他更改更新此值…

在后面的代码中,Value。status被更新时,status属性的setter会触发一个propertyChanged。但是前端没有捕获任何东西。

public OverallStatus status
    {
        get { return this.Status; }
        set { this.Status = value; onPropertyChanged(this, "status"); }
    }

绑定到Value的属性语法是什么?属性(目前根本不起作用)并让它识别从视图向下3层的propertyChanged setter

数据绑定到对象的KVP,对象不允许实时使用或更新属性

我已经创建了一个显示嵌套属性的示例。当我在单击按钮时更改属性值时,它会反映在网格中。更多内容可点击此处阅读:属性路径语法

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="524.627" Width="862.313">
    <StackPanel>
        <DataGrid x:Name="Dgrd" HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top" AutoGenerateColumns="False">
            <DataGrid.Columns>
                <DataGridTextColumn Binding="{Binding Value.Status.Name}" ClipboardContentBinding="{x:Null}" Header="Status"/>
            </DataGrid.Columns>
        </DataGrid>
        <Button Content="Button" HorizontalAlignment="Left" Margin="29,38,0,0" Grid.Row="1" VerticalAlignment="Top" Width="75" Click="Button_Click"/>
    </StackPanel>
</Window>

using System;
using System.ComponentModel;
using System.Collections.ObjectModel;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
namespace WpfApplication1
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {  
            InitializeComponent();
            Dgrd.ItemsSource = DataStore.Operations;
        }
        private void Button_Click(object sender, RoutedEventArgs e)
        {
            DataStore.Operations[0].Value.Status.Name = "N/A"; // change first item
        }
    }
    public class DataStore
    {
        //static List<Operation> _operations;
        public static List<Operation> Operations;
        static DataStore()
        {
            Operations =
                new List<Operation>() { 
                    new Operation(){ Value = new RecordInner(){ Status = new OverallStatus (){ Name="Pending"}}},
                    new Operation(){ Value = new RecordInner(){ Status = new OverallStatus (){ Name="Started"}}},
                    new Operation(){ Value = new RecordInner(){ Status = new OverallStatus (){ Name="Completed"}}}
                };
        }
    }
    public class Operation
    {
        RecordInner _value;
        public RecordInner Value
        {
            get { return _value; }
            set { _value = value; }
        }
    }
    public class RecordInner
    { 
        OverallStatus _status;
        public OverallStatus Status
        {
            get { return _status; }
            set { _status = value; }
        }
    }
    public class OverallStatus:INotifyPropertyChanged
    {
        string _name;
        public string Name { get { return _name; } set { _name = value; OnPropertyChanged("name"); } }
        public event PropertyChangedEventHandler PropertyChanged;
        public void OnPropertyChanged(string name)
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(name));
        }
    }
}