提问人:Harlan 提问时间:11/17/2023 更新时间:11/20/2023 访问量:71
组合框未在 Avalonia 应用程序中填充
Combo Box not being populated in Avalonia Application
问:
我在未填充的窗体上有一个组合框,即使当我单步执行代码时,我也可以看到值已分配给属性。我在这里错过了什么:
.axaml
<UserControl
xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:vm="clr-namespace:TAStagingApp.ViewModels.Implementations.Terminal;assembly=TAStagingApp.ViewModels"
xmlns:terminal="clr-namespace:TAStagingApp.Views.Terminal;assembly=TAStagingApp"
mc:Ignorable="d"
d:DesignWidth="800"
d:DesignHeight="450"
x:DataType="vm:TerminalConfigureViewModel"
x:Class="TAStagingApp.Views.Terminal.TerminalConfigureView"
Background="{StaticResource TABackgroundColor}">
<UserControl.DataContext>
<vm:TerminalConfigureViewModel />
</UserControl.DataContext>
<UserControl.Styles>
<StyleInclude Source="/Styles/ConfigureViews/Configure.ComboBoxes.axaml" />
<StyleInclude Source="/Styles/ConfigureViews/Configure.LabelStyles.axaml" />
<StyleInclude Source="/Styles/ConfigureViews/Configure.StackPanels.axaml" />
</UserControl.Styles>
<UserControl.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceInclude Source="/Styles/ConfigureViews/Configure.Buttons.axaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</UserControl.Resources>
<Grid
ColumnDefinitions="*, Auto, Auto, *"
RowDefinitions="*, Auto, Auto, Auto, Auto, *"
Classes="StagingGrid">
<!-- Instructions Row -->
<Label
Classes="ConfigureH1"
Grid.Row="1"
Grid.Column="1"
Grid.ColumnSpan="2">
PLEASE ENTER THE FOLLOWING INFORMATION:
</Label>
<!-- Site ID Row -->
<StackPanel
Grid.Row="2"
Grid.Column="1"
Classes="ServerConfigureStackPanel">
<Label
Classes="ConfigureH2">
SITE ID:
</Label>
<ComboBox
Classes="Configure"
Width="296"
Margin="10 5 5 10"
ItemsSource="{Binding SiteIds}"
SelectedItem="{Binding SiteId, Mode=TwoWay}">
<ComboBox.ItemTemplate>
<DataTemplate>
<ComboBoxItem>
<ComboBoxItem.Content>
<Binding Path="SiteId" />
</ComboBoxItem.Content>
</ComboBoxItem>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
</StackPanel>
<!-- Device -->
<StackPanel
Grid.Row="3"
Grid.Column="1"
Classes="ServerConfigureStackPanel">
<Label
Classes="ConfigureH2">
DEVICE:
</Label>
<ComboBox
Classes="Configure"
Width="296"
Margin="10 5 5 10"
ItemsSource="{Binding Terminals}"
SelectedItem="{Binding Terminal}">
<ComboBox.ItemTemplate>
<DataTemplate>
<ComboBoxItem>
<ComboBoxItem.Content>
<Binding Path="DeviceName" />
</ComboBoxItem.Content>
</ComboBoxItem>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
</StackPanel>
<!-- Configure Button -->
<Button
Grid.Column="1"
Grid.Row="4"
Grid.ColumnSpan="2"
Command="{Binding Configure}"
Theme="{DynamicResource ConfigureButton}">
CONFIGURE
</Button>
</Grid>
</UserControl>
C#
namespace TAStagingApp.ViewModels.Implementations.Terminal;
public class TerminalConfigureViewModel : ViewModelBase, IConfigureViewModel
{
private readonly ObservableCollection<SiteIdModel>? _siteIds;
private readonly ObservableCollection<TerminalModel>? _terminals;
private readonly IMediator? _mediator;
private SiteIdModel? _siteId;
private TerminalModel? _terminal;
public TerminalConfigureViewModel(IMediator mediator)
{
_mediator = mediator;
_siteIds = [];
_terminals = [];
}
public TerminalConfigureViewModel()
{
}
public IEnumerable<SiteIdModel>? SiteIds => _siteIds;
public IEnumerable<TerminalModel>? Terminals => _terminals;
public SiteIdModel? SiteId
{
get => _siteId;
set
{
_siteId = value;
this.RaiseAndSetIfChanged(ref _siteId, value);
this.RaisePropertyChanged(nameof(Terminals));
if (_siteId == value)
{
_terminals!.Clear();
GetNewTerminalList();
}
}
}
[Reactive]
public TerminalModel? Terminal { get; set; }
public async void Activate()
{
_siteIds!.AddRange(await GetSiteIdListAsync());
_siteId = SiteId = _siteIds![0];
_terminal = Terminal = _terminals![0];
}
public void Configure()
{
throw new NotImplementedException();
}
private async void GetNewTerminalList()
{
var query = new ListDevicesBySiteIdQuery(_siteId!.SiteId!);
var queryResult = await _mediator!.Send(query);
var terminals = new List<TerminalModel>();
foreach (var result in queryResult.Value)
{
terminals.Add(new TerminalModel(
result.Site!.SiteNumber,
result.TerminalName));
}
_terminals!.AddRange(terminals);
_terminal = Terminal = _terminals![0];
}
private async Task<List<SiteIdModel>> GetSiteIdListAsync()
{
var query = new ListSitesQuery();
var queryResult = await _mediator!.Send(query);
var siteIds = new List<SiteIdModel>();
foreach (var result in queryResult.Value)
{
siteIds.Add(new SiteIdModel(result.SiteNumber));
}
return [.. siteIds.OrderBy(x => x.SiteId)];
}
}
如果我单步执行视图模型,我可以看到所有属性都已正确填充。但 UI 中不显示任何内容。
谢谢
答:
0赞
Tarazed
11/20/2023
#1
您正在向 ObservableCollection 添加内容,但仅限于支持字段。
private readonly ObservableCollection<SiteIdModel>? _siteIds;
但是,可访问属性是 IEnumerable。IEnumerable 可以是 ObservableCollection,但它也可以是一个简单的数组和其他几个东西。视图只能访问 IEnumerable 中定义的成员。
public IEnumerable<SiteIdModel>? SiteIds => _siteIds;
将属性更改为 ObservableCollection,以便在填充列表时通知视图并更新 ItemsSource。
public ObservableCollection<SiteIdModel>? SiteIds => _siteIds;
评论
0赞
Harlan
11/21/2023
我试过了,得到了同样的结果。在 UI 中,“站点 ID”组合框为空,但在代码中,但字段和属性已完全填充。是什么原因导致的?_siteIds
SiteIds
0赞
Tarazed
11/21/2023
在这种情况下,您将不得不尝试制作一个最小的可重现示例。
0赞
Harlan
11/21/2023
我创建了一个测试应用程序,它按照我期望的方式工作,但我仍然无法弄清楚整个应用程序中出了什么问题。https://github.com/hmsiegel/TestAvalonia
评论