过去几天这个问题一直困扰着我。该窗口是基本地址条目,通过查询数据库并显示结果。
用户首先进入街道(Bound to Query.Street),然后是city(Bound to Query.City),然后从结果列表(DataGrid绑定到QueryResults)中选择适当的街道。
查询数据库是在ViewModel中的Query对象的PropertyChanged中完成的,它运行良好。我将ObservableCollection<Location> QueryResults
绑定到DataGrid ItemsSource,当QueryResults中只剩下一个项目时,我将其分配给Location SelectedAddress
,如此(this
是ViewModel):
this.PropertyChanged += (sender, e) =>
{
switch (e.PropertyName)
{
case "QueryResults":
// QueryResult contains only one result
if (this.QueryResults?.Count == 1)
{
// select that result
this.SelectedAddress = this.QueryResults.First();
}
break;
default:
break;
}
};
我在ViewModel构造函数中订阅了这个事件。
ViewModel中的 QueryResults
:
internal ObservableCollection<Location> _queryResults = new ObservableCollection<Location>();
public ObservableCollection<Location> QueryResults
{
get { return this._queryResults; }
set
{
this._queryResults.Clear();
if (value != null)
{
foreach (var item in value)
{
this._queryResults.Add(item);
}
}
OnPropertyChanged("QueryResults");
}
}
这是SelectedAddress
属性:
internal Location _selectedAddress = new Location();
public Location SelectedAddress
{
get { return this._selectedAddress; }
set
{
this._selectedAddress = value;
OnPropertyChanged("SelectedAddress");
}
}
然后我将this.SelectedAddress
绑定到DataGrid的SelectedItem
,以便它可以直观地选择它。 DataGrid代码:
<DataGrid Name="dgQueryResults"
MaxHeight="212.6"
RowHeaderWidth="0"
AutoGenerateColumns="False"
CanUserAddRows="False"
CanUserDeleteRows="False"
CanUserReorderColumns="False"
CanUserResizeRows="False"
IsReadOnly="True"
VerticalScrollBarVisibility="Hidden"
ItemsSource="{Binding QueryResults}"
SelectionMode="Single"
SelectionUnit="FullRow"
SelectedItem="{Binding SelectedAddress, Mode=TwoWay}"
SelectionChanged="dgQueryResults_SelectionChanged"
>
<DataGrid.Resources>
<SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="LightGreen"/>
<SolidColorBrush x:Key="{x:Static SystemColors.ControlBrushKey}" Color="LightGreen"/>
<Style TargetType="{x:Type DataGridCell}" BasedOn="{StaticResource {x:Type DataGridCell}}">
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="Foreground" Value="Black"/>
</Style>
</DataGrid.Resources>
<DataGrid.Columns>
<DataGridTextColumn Width="*" Binding="{Binding Street}" IsReadOnly="True">
<DataGridTextColumn.Header>
<TextBlock Text="Street"/>
</DataGridTextColumn.Header>
</DataGridTextColumn>
<DataGridTextColumn Width="*" Binding="{Binding City}" IsReadOnly="True">
<DataGridTextColumn.Header>
<TextBlock Text="City"/>
</DataGridTextColumn.Header>
</DataGridTextColumn>
<DataGridTextColumn Width="*" Binding="{Binding Municipality}" IsReadOnly="True">
<DataGridTextColumn.Header>
<TextBlock Text="Municipality"/>
</DataGridTextColumn.Header>
</DataGridTextColumn>
</DataGrid.Columns>
</DataGrid>
dgQueryResults_SelectionChanged
只有ScrollIntoView
所选行。
SelectedAddress
也绑定到一个面板,该面板显示所选地址和描述(这是ViewModel中的一个独立属性,当它发生更改时会被复制到SelectedAddress
)用户可以输入,以便用户可以仔细检查他们是否选择了正确的地址:
<DockPanel>
<TextBlock DockPanel.Dock="Top" Text="Selected address" FontWeight="DemiBold"/>
<DockPanel DockPanel.Dock="Bottom">
<TextBlock DockPanel.Dock="Top" Text="Floor, extra description:"/>
<TextBlock DockPanel.Dock="Bottom" Text="{Binding Description}"/>
</DockPanel>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center" DataContext="{Binding SelectedAddress}">
<StackPanel>
<TextBlock Text="Street" HorizontalAlignment="Left"/>
<TextBlock Text="{Binding Street}" HorizontalAlignment="Left"/>
</StackPanel>
<StackPanel>
<TextBlock Text="House number" HorizontalAlignment="Left"/>
<TextBlock Text="{Binding HouseNumber}" HorizontalAlignment="Left"/>
</StackPanel>
<StackPanel>
<TextBlock Text="City" HorizontalAlignment="Left"/>
<TextBlock Text="{Binding City}" HorizontalAlignment="Left"/>
</StackPanel>
<StackPanel>
<TextBlock Text="Municipality" HorizontalAlignment="Left"/>
<TextBlock Text="{Binding Municipality}" HorizontalAlignment="Left"/>
</StackPanel>
</StackPanel>
</DockPanel>
问题是当DataGrid中只剩下一个项目时(或同样位于QueryResults
中),我想自动选择它(我在{{1时检查)更改,如果它只包含一个项目,则将其分配给QueryResults
),以便DataGrid更新其选定的项目。这不会发生。 ViewModel中的SelectedAddress
属性发生更改,调用SelectedAddress
,但DataGrid不会选择剩余的唯一行,也不会更新DockPanel。但是,当我单击DataGrid中的一行时,OnPropertyChanged("SelectedAddress");
会更新,DockPanel会立即更新。
非常感谢任何帮助!
提前致谢!
修改:SelectedAddress
更改有效时重置窗口DataContext
,但这是我不想使用的解决方法。
答案 0 :(得分:0)
我明白了。
即使我正在提升PropertyChanged
事件,我也没有表明我的ViewModel
实现了接口INotifyPropertyChanged
,因此这就是为什么更改没有反映在UI上。