上下文
网络上是用UDP定期宣传其名称的服务器。
数据报在1967年的端口上,并包含一个类似的字符串:
UiProxy SomeServerMachineName
添加了新的条目,现有条目已更新,而陈旧的条目则是可观察的收藏中的年龄,该集合用作XAML组合框的物品。
。这是组合框
<ComboBox x:Name="comboBox" ItemsSource="{Binding Directory}" />
这是支持代码。例外处理人员包裹了所有危险的东西,但在这里简洁地省略了。
public class HostEntry
{
public string DisplayName { get; set;}
public HostName HostName { get; set; }
public DateTime LastUpdate { get; set; }
public HostEntry(string displayname, HostName hostname)
{
DisplayName = displayname;
HostName = hostname;
LastUpdate = DateTime.Now;
}
public override string ToString()
{
return DisplayName;
}
}
HostEntry _selectedHost;
public HostEntry SelectedHost
{
get { return _selectedHost; }
set
{
_selectedHost = value;
UpdateWriter();
}
}
async UpdateWriter() {
if (_w != null)
{
_w.Dispose();
_w = null;
Debug.WriteLine("Disposed of old writer");
}
if (SelectedHost != null)
{
_w = new DataWriter(await _ds.GetOutputStreamAsync(SelectedHost.HostName, "1967"));
Debug.WriteLine(string.Format("Created new writer for {0}", SelectedHost));
}
}
ObservableCollection<HostEntry> _directory = new ObservableCollection<HostEntry>();
public ObservableCollection<HostEntry> Directory
{
get { return _directory; }
}
private async void _ds_MessageReceived(DatagramSocket sender, DatagramSocketMessageReceivedEventArgs args)
{
if (_dispatcher == null) return;
await _dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
{
var dr = args.GetDataReader();
var raw = dr.ReadString(dr.UnconsumedBufferLength);
var s = raw.Split();
if (s[0] == "UiProxy")
{
if (_directory.Any(x => x.ToString() == s[1]))
{ //update
_directory.Single(x => x.ToString() == s[1]).LastUpdate = DateTime.Now;
}
else
{ //insert
_directory.Add(new HostEntry(s[1], args.RemoteAddress));
}
var cutoff = DateTime.Now.AddSeconds(-10);
var stale = _directory.Where(x => x.LastUpdate < cutoff);
foreach (var item in stale) //delete
_directory.Remove(item);
}
});
}
集合开始空。
从SelecteShost销毁的设置器中调用的UpdateWrite方法(如有必要),并在datagramsocket周围创建(如果可能的话)dataWriter,该数据量涉及datagramsocket,该datagramsocket针对Selectedhost的值所描述的地址。
。目标
自动选择添加值时,列表停止为空。
列表也可以变为空。发生这种情况时,选择必须以-1的选定索引返回到NULL。
在事物的立场上,列表被管理,并且可以从列表中交互式选择服务器。
目前我将Selected Host设置为这样,但我敢肯定它可以通过绑定来完成。
private void comboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
SelectedHost = comboBox.SelectedItem as HostEntry;
}
selectedhost调用createWriter的设置器方法,该方法管理在其他地方将数据发送到所选主机的对象。我已经从设定器打电话给它,因为它必须始终在价值发生变化之后,而且在任何其他时间都会发生。它是一种方法,因此可以是异步。
我可以将其移至SelectionChanged处理程序,但是如果我这样做,那么我该如何保证执行顺序?
问题
尝试编程设置组合框的选择时会出现错误。我正在划定UI线程,但事情仍然不好。正确的方法是什么?我已经尝试设置SelectedIndex和Selected Value。
当我尝试编程设置组合框的选择时,我会出现错误。
你好吗?在代码方面,只要您注定要在该索引上包含一个项目:
myComboBox.SelectedIndex = 4;
,但我确定它可以通过绑定
来完成
是的,看起来您忘了实现InotifyPropertyChanged。另外,由于您正在使用UWP,因此有一种新的改进的绑定语法Bind
,而不是Binding
在此处了解更多:https://msdn.microsoft.com/en-us/windows/uwindows/uwdata-data-binding/data-binding/data-binding-in-data-binding-in-data-in-data-in-depth-in-data-in-depth-in
<ComboBox x:Name="comboBox" ItemsSource="{Binding Directory}"
SelectedItem="{Binding SelectedHost}" />
public event PropertyChangedEventHandler PropertyChanged;
HostEntry _selectedHost;
public HostEntry SelectedHost
{
get { return _selectedHost; }
set
{
_selectedHost = value;
RaiseNotifyPropertyChanged();
// What is this? propertys should not do things like this CreateWriter();
}
}
// This method is called by the Set accessor of each property.
// The CallerMemberName attribute that is applied to the optional propertyName
// parameter causes the property name of the caller to be substituted as an argument.
private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}