为什么我的文本框中的数据绑定不起作用?

Why does the Data Binding in my Textbox not work?

我在文本框中的数据绑定不起作用。在不同的 Window 中,我在 GridView 上有相同的绑定,这有效。它们具有相同的 DataContext。将 TraceLevel 设置为高以进行调试后,我收到了一些警告。但他们并没有真正帮助我:

System.Windows.Data Warning: 56 : Created BindingExpression (hash=14200498) for Binding (hash=9369539)
System.Windows.Data Warning: 58 :  Path: 'KundeVM.Skunde.Plz'
System.Windows.Data Warning: 62 : BindingExpression (hash=14200498): Attach to System.Windows.Controls.TextBox.Text (hash=2601186)
System.Windows.Data Warning: 67 : BindingExpression (hash=14200498): Resolving source 
System.Windows.Data Warning: 70 : BindingExpression (hash=14200498): Found data context element: TextBox (hash=2601186) (OK)
System.Windows.Data Warning: 78 : BindingExpression (hash=14200498): Activate with root item AppViewModel (hash=35104124)
System.Windows.Data Warning: 107 : BindingExpression (hash=14200498):   At level 0 using cached accessor for AppViewModel.KundeVM: RuntimePropertyInfo(KundeVM)
System.Windows.Data Warning: 104 : BindingExpression (hash=14200498): Replace item at level 0 with AppViewModel (hash=35104124), using accessor RuntimePropertyInfo(KundeVM)
System.Windows.Data Warning: 101 : BindingExpression (hash=14200498): GetValue at level 0 from AppViewModel (hash=35104124) using RuntimePropertyInfo(KundeVM): KundeViewModel (hash=39638585)
System.Windows.Data Warning: 107 : BindingExpression (hash=14200498):   At level 1 using cached accessor for KundeViewModel.Skunde: RuntimePropertyInfo(Skunde)
System.Windows.Data Warning: 104 : BindingExpression (hash=14200498): Replace item at level 1 with KundeViewModel (hash=39638585), using accessor RuntimePropertyInfo(Skunde)
System.Windows.Data Warning: 101 : BindingExpression (hash=14200498): GetValue at level 1 from KundeViewModel (hash=39638585) using RuntimePropertyInfo(Skunde): <null>
System.Windows.Data Warning: 106 : BindingExpression (hash=14200498):   Item at level 2 is null - no accessor
System.Windows.Data Warning: 80 : BindingExpression (hash=14200498): TransferValue - got raw value {DependencyProperty.UnsetValue}
System.Windows.Data Warning: 88 : BindingExpression (hash=14200498): TransferValue - using fallback/default value ''
System.Windows.Data Warning: 89 : BindingExpression (hash=14200498): TransferValue - using final value ''

文本框绑定:

                <TextBox Grid.Column="0" Grid.Row="6" Grid.ColumnSpan="2" MaxLength="5" Margin="10 5 " HorizontalContentAlignment="Left" VerticalContentAlignment="Center" Text="{Binding KundeVM.Skunde.Plz,  UpdateSourceTrigger=PropertyChanged, Mode = TwoWay, diag:PresentationTraceSources.TraceLevel=High}">
                </TextBox>

DataGrid 绑定:

            <DataGrid x:Name="MCDaten" ItemsSource="{Binding KundeVM.Kunden}" IsReadOnly="True" SelectedItem="{Binding KundeVM.Skunde, Mode=OneWayToSource}" AutoGenerateColumns="False" >
                <DataGrid.Columns>
                    <DataGridTextColumn Header="Kundennummer" Binding="{Binding Kunnr, BindsDirectlyToSource=True, Mode=OneWay, UpdateSourceTrigger=Default}"></DataGridTextColumn>
                    <DataGridTextColumn Header="Name" Binding="{Binding Name, UpdateSourceTrigger=PropertyChanged}"></DataGridTextColumn>
                    <DataGridTextColumn Header="Branche" Binding="{Binding Branche, UpdateSourceTrigger=PropertyChanged}"></DataGridTextColumn>
                    <DataGridTextColumn Header="Straße" Binding="{Binding Strasse, UpdateSourceTrigger=PropertyChanged}"></DataGridTextColumn>
                    <DataGridTextColumn Header="PLZ" Binding="{Binding Plz, UpdateSourceTrigger=PropertyChanged}"></DataGridTextColumn>
                    <DataGridTextColumn Header="Ort" Binding="{Binding Ort, UpdateSourceTrigger=PropertyChanged}"></DataGridTextColumn>
                </DataGrid.Columns>

斯昆德 属性:

        private Kunde _skunde;

        public Kunde Skunde
        {
            get { return _skunde; }
            set { OnPropertyChanged(ref _skunde, value); }
        }

AppViewModel:

    class AppViewModel : ObservableObject
    {
        private object _currentView;
        public object CurrentView
        {
            get { return _currentView; }
            set { OnPropertyChanged(ref _currentView, value); }
        }

        private KundeViewModel _kundeVM;
        public KundeViewModel KundeVM
        {
            get { return _kundeVM; }
            set { OnPropertyChanged(ref _kundeVM, value); }
        }

        public AppViewModel()
        {
            KundeVM = new KundeViewModel();
            CurrentView = KundeVM;
        }



    }
}

昆德语:

        private int _id;
        public int Id
        {
            get { return _id; }
            set { OnPropertyChanged(ref _id, value); }
        }

        private int _kunnr;
        public int Kunnr
        {
            get { return _kunnr; }
            set { OnPropertyChanged(ref _kunnr, value); }
        }

        private string _name;
        public string Name
        {
            get { return _name; }
            set { OnPropertyChanged(ref _name, value); }
        }

        private string _branche;
        public string Branche
        {
            get { return _branche; }
            set { OnPropertyChanged(ref _branche, value); }
        }

        private string _strasse;
        public string Strasse
        {
            get { return _strasse; }
            set { OnPropertyChanged(ref _strasse, value); }
        }

        private int _plz;
        public int Plz
        {
            get { return _plz; }
            set { OnPropertyChanged(ref _plz, value); }
        }

        private string _ort;
        public string Ort
        {
            get { return _ort; }
            set { OnPropertyChanged(ref _ort, value); }
        }

我很新,我尝试了很多东西但没有任何帮助。

我没有错误或警告。

问题是它不起作用,因为我有单独的文本框和数据网格 windows。 windows 都具有相同的 DataContext。 如果我把它放在同一个 window 中,一切正常,但这不是我需要的。

结构Structure

感谢帮助

根据我的记忆和遇到的情况,您不能执行由 3 部分组成的绑定参考,例如将文本框设置为“KundeVM.Skunde.Plz”(viewModel.secondaryObject.someProperty)。要解决此问题,您应该在表单级别或内部控件更新“DataContext”。

如果您的所有控件总是以某种方式绑定到“KundeVM”对象,那么在您的 form/window 级别,设置它的

DataContext = {Binding KundeVM}

然后,在您的 form/window 中的其他任何地方,您都不需要 KundeVM 的额外上下文。从那个级别开始的所有内容都将默认为......哦,那是我的东西......这样做,你的文本绑定将下降到只是“Skunde.Plz”。

现在,如果您的 KundeVM 级别有多个 objects/properties,您仍然可以通过向 KundeVM 声明 ITS 数据上下文来调整文本框,然后文本将成为特定的基础源。这样,您就不会弄乱 form/window 绑定的其余部分。 (去掉其他不重要的东西)

 <TextBox Text="{Binding KundeVM.Skunde.Plz}" />

会变成

 <TextBox DataContext={Binding KundeVM} Text="{Binding Skunde.Plz}" />

但如果你达到 window 水平

<Window x:Class="YourAppNamespace.YourClass" 
    DataContext="{Binding KundeVM}" 
    ... rest of window stuff ... >


    <DataGrid ItemsSource="{Binding Kunden}" IsReadOnly="True" 
        SelectedItem="{Binding Skunde, Mode=OneWayToSource}" AutoGenerateColumns="False" >
        <.. rest of data grid content .. >
    </DataGrid
           
     <TextBox Text="{Binding Skunde.Plz}" />

</Window>

注意第二个示例,在 window 级别的数据上下文中,您从 KundeVM 开始,因此 window 中的所有其他内容都是从该点开始的子 property/object。这有助于解决您的问题吗?

我做了一个示例源,效果很好。
你会试试这个吗?完整源代码在 Github.

结构

AppViewModel

public class AppViewModel : ObservableObject
{
    private object _currentView;
    public object CurrentView
    {
        get { return _currentView; }
        set { _currentView = value; OnPropertyChanged(); }
    }

    private KundeViewModel _kundeVM;
    public KundeViewModel KundeVM
    {
        get { return _kundeVM; }
        set { _kundeVM = value; OnPropertyChanged(); }
    }

    public AppViewModel()
    {
        KundeVM = new KundeViewModel();
        CurrentView = KundeVM;
    }
}

昆德视图模型

我在加载KundeViewModel时填充了Kunden

public class KundeViewModel : ObservableObject
{
    private Kunde _skunde;
    public Kunde Skunde
    {
        get { return _skunde; }
        set { _skunde = value; OnPropertyChanged(); }
    }

    private ObservableCollection<Kunde> _kunden;
    public ObservableCollection<Kunde> Kunden
    {
        get { return _kunden; }
        set { _kunden = value; OnPropertyChanged(); }
    }

    public KundeViewModel()
    {
        Kunden = GetKunden();
    }

    private ObservableCollection<Kunde> GetKunden()
    {
        ObservableCollection<Kunde> source = new ObservableCollection<Kunde>
        {
            new Kunde { Plz = 0 },
            new Kunde { Plz = 1 },
            new Kunde { Plz = 2 },
            new Kunde { Plz = 3 },
            new Kunde { Plz = 4 }
        };
        return source;
    }
}

AppView.xaml

<Grid VerticalAlignment="Top">
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="Auto"/>
        <ColumnDefinition Width="*"/>
    </Grid.ColumnDefinitions>

    <DataGrid x:Name="MCDaten"
              ItemsSource="{Binding KundeVM.Kunden}" 
              SelectedItem="{Binding KundeVM.Skunde, Mode=OneWayToSource}"
              IsReadOnly="True" AutoGenerateColumns="False" Margin="30" Grid.Column="0">
        <DataGrid.Columns>
            <DataGridTextColumn Header="PLZ" Binding="{Binding Plz, UpdateSourceTrigger=PropertyChanged}"/>
        </DataGrid.Columns>
    </DataGrid>

    <TextBox Grid.Column="1" MaxLength="5" Width="300" Height="30"
             Text="{Binding KundeVM.Skunde.Plz, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"/>
</Grid>

AppView.xaml.cs

public partial class AppView : UserControl
{
    public AppView()
    {
        InitializeComponent();
        DataContext = new AppViewModel();
    }
}

结果

  • 当select网格项

  • 改变TextBox的值时