为什么我的文本框中的数据绑定不起作用?
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
的值时
我在文本框中的数据绑定不起作用。在不同的 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
的值时