paj*_*777 5 c# wpf xaml binding dependency-properties
我在绑定 UserControl 中的依赖项属性时遇到问题。当它初始化时,它会得到一个值,但它不会更新。我可能错过了一些明显的东西,这里有一些代码片段:
这是我绑定BalanceContent
依赖属性的地方:
<Game:PlayerDetails x:Name="SelectedPlayerDetails" Grid.Row="1" Grid.Column="2" Grid.ColumnSpan="2" Grid.RowSpan="4"
BalanceContent="{Binding Source={StaticResource UserData}, Path=SelectedUser.Balance, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}">
</Game:PlayerDetails>
Run Code Online (Sandbox Code Playgroud)
这是TextBox
在UserControl
:
<TextBox VerticalAlignment="Center" FontFamily="Formata" FontSize="20" Grid.Column="2"
Text="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type UserControl}}, Path=BalanceContent}"
Grid.Row="7"></TextBox>
Run Code Online (Sandbox Code Playgroud)
这是依赖属性:
public static readonly DependencyProperty BalanceContentProperty = DependencyProperty.Register(
"BalanceContent", typeof(string), typeof(PlayerDetails));
public string BalanceContent
{
get
{return (string) GetValue(BalanceContentProperty);}
set
{SetValue(BalanceContentProperty, value);}
}
Run Code Online (Sandbox Code Playgroud)
以下是更新所选用户的列表,该列表位于使用 UserControl 的视图中:
<ListView x:Name="lstAccounts" Grid.Column="0" Grid.Row="2" Grid.ColumnSpan="2" Grid.RowSpan="4"
ItemsSource="{Binding Source={StaticResource UserData}, Path=CurrentUserSearch}"
SelectedItem="{Binding Source={StaticResource UserData}, Path=SelectedUser}"
Run Code Online (Sandbox Code Playgroud)
并SelectedUser
在一个实现的类中定义INotifyPropertyChanged
:
public User SelectedUser
{
get
{
return _selectedUser;
}
set
{
_selectedUser = value;
OnPropertyChanged(new PropertyChangedEventArgs("SelectedUser"));
}
}
Run Code Online (Sandbox Code Playgroud)
这个想法是当在列表中选择一个新用户时 TextBox 应该更新,但目前它没有这样做。我已经将绑定放在本地 TextBox 上并且它更新得很好,只是不在DependencyProperty
. 任何帮助表示赞赏。
您可以尝试以下一些可能性:
首先,您的 ListView 可能不会更新您的 ViewModel 的 SelectedUser 属性。尝试将 ListView 中的绑定设置为“TwoWay”模式:
<ListView x:Name="lstAccounts" Grid.Column="0" Grid.Row="2" Grid.ColumnSpan="2" Grid.RowSpan="4"
ItemsSource="{Binding Source={StaticResource UserData}, Path=CurrentUserSearch}"
SelectedItem="{Binding Source={StaticResource UserData}, Path=SelectedUser, Mode=TwoWay}"/>
Run Code Online (Sandbox Code Playgroud)
您可以更好地组织 DataContext 的定义方式。请记住,UserControl 的所有子控件都可以访问其 DataContext,而无需使用相对绑定(它们继承它)。由于您的 PlayerInfo 控件依赖于 SelectedUser,因此请考虑将其 DataContext 设置为 SelectedUser,将其绑定到 ListView 的 SelectedUser 或 UserData 视图模型中的 SelectedUser。
<Game:PlayerDetails x:Name="SelectedPlayerDetails" Grid.Row="1" Grid.Column="2" Grid.ColumnSpan="2" Grid.RowSpan="4" DataContext="{Binding Source={StaticResource UserData}, Path=SelectedUser}"
BalanceContent="{Binding Balance, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}">
</Game:PlayerDetails>
Run Code Online (Sandbox Code Playgroud)
当前 SelectedUser 的来源也可以是 ListView:
<Game:PlayerDetails x:Name="SelectedPlayerDetails" Grid.Row="1" Grid.Column="2" Grid.ColumnSpan="2" Grid.RowSpan="4" DataContext="{Binding SelectedItem, ElementName=lstAccounts}"
BalanceContent="{Binding Balance, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}">
</Game:PlayerDetails>
Run Code Online (Sandbox Code Playgroud)
无论哪种方式,您都可以在 TextBox 上执行以下操作,因为它的 DataContext 将与其父级的 DataContext 相同:
<TextBox VerticalAlignment="Center" FontFamily="Formata" FontSize="20" Grid.Column="2"
Text="{Binding Balance}"
Grid.Row="7"></TextBox>
Run Code Online (Sandbox Code Playgroud)
如果用户控件依赖于根视图模型来执行命令和其他高级逻辑等操作,则以可以轻松访问 SelectedUser 的方式将 DataContext 设置为它。
<Game:PlayerDetails x:Name="SelectedPlayerDetails" Grid.Row="1" Grid.Column="2" Grid.ColumnSpan="2" Grid.RowSpan="4" DataContext="{StaticResource UserData}"
BalanceContent="{Binding SelectedUser.Balance, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}">
</Game:PlayerDetails>
Run Code Online (Sandbox Code Playgroud)
所以你可以这样做:
<TextBox VerticalAlignment="Center" FontFamily="Formata" FontSize="20" Grid.Column="2"
Text="{Binding SelectedUser.Balance}"
Grid.Row="7"></TextBox>
Run Code Online (Sandbox Code Playgroud)
然而,在第二种方法中,您必须检查我不确定的一件事。我知道当控件的 DataContext 更改时,它会更新所有依赖的绑定。例如,如果您将 PlayerDetails DataContext 更改为另一个 UserData 实例,则 BalanceContent 属性也会更新。但是,在这种情况下,BalanceContent 取决于 UserData 的 SelectedUser 的属性。因此它将监听该 User 实例的属性更改。如果 SelectedUser.Balance 更改(并且 User 实现 INotifyPropertyChanged,或者它是 DependencyProperty),BalanceContent 将更新。现在,如果 UserData 中的 SelectedUser 实例发生更改,我不确定 BalanceContent 是否会更新,因为我认为绑定不会监听其路径中每个对象的更改。
编辑
最后一点可能是我在使用 xaml 开发时遇到的第一个问题。我在 Silverlight 中有一个 DataGrid,其实体类型具有复杂类型的属性。其中一列取决于复杂类型的属性。如果我更改复杂类型的值,该列将很好地更新(它实现了 INPC)。如果我更改实体的复杂类型实例,该列将不会...解决方案是级联 DataContext:我创建了一个模板列,为复杂类型设置列的绑定,而不是其属性。然后,我将模板的 TextBox 的文本绑定到复杂类型的属性,因为它现在是 TextBox 的 DataContext。
在您的情况下,您可以对 TextBox.Text 执行此操作,但不能对 PlayerDetails.BalanceContent 执行此操作。您可以将 TextBox.DataContext 绑定到 UserData 的 SelectedUser,然后将 Text 绑定到 Balance 属性。
<TextBox VerticalAlignment="Center" DataContext="{Binding SelectedUser}" FontFamily="Formata" FontSize="20" Grid.Column="2"
Text="{Binding Balance}"
Grid.Row="7"></TextBox>
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
11265 次 |
最近记录: |