MVVM可编辑组合框,而不更改SelectedItem



我和这个用户有完全相同的要求:MVVM可编辑组合框绑定。

我已经尝试了公认的答案:

"绑定一个类似"的属性;EditedServerName"到Combobox.Text。当"EditedServerName"则可以将值设置为"ServerName"的SelectedServer">

但它不起作用,因为当我试图拦截";EditedServerName";选择的服务器";为null。我相信这是因为控件试图搜索";ServerName"在集合中正在编辑的,显然无法检索元素。当我开始编辑时,这是非常清楚的;ServerID";马上就空了。

XAML:

<ComboBox IsEditable= "True" 
ItemsSource= "{Binding Servers}"
DisplayMemberPath= "ServerName"
SelectedItem="{Binding SelectedServer}"
Text= "{Binding EditedServerName, UpdateSourceTrigger=LostFocus}" />
<TextBlock Text="{Binding SelectedServer.ServerID}"/>

ViewModel:

public List<Server> Servers { get; set; }
public Server SelectedServer { get; set; }
private string editedServerName;
public string EditedServerName
{
get { return editedServerName; }
set 
{ 
editedServerName = value;
SelectedServer.ServerName = value;
}
}
public MainViewModel()
{
Servers = new List<Server>();
Servers.Add(new Server { ServerID = 0, ServerName = "Local" });
Servers.Add(new Server { ServerID = 1, ServerName = "Remote" });
}

我知道我可以暂时存储";选择的服务器";在另一个物体上,但如果可能的话,我希望能更好地转身。

两件事:

  1. 您的MainViewModel没有正确使用INotifyPropertyChanged接口,建议使用该接口将数据绑定回视图。这就是您当前发布的代码没有对UI进行更改的原因。

  2. 你说的没错,一旦EditedServerName被更改,SelectedServer将变成null,但对于点1,它也会到达那个点。即使我们修复代码以适应数据绑定,SelectedServer属性也不会处理null

考虑到这一点,如果我们修改代码以适应以上几点,代码可能会是什么样子:

下面的代码有助于通知视图我们的模型/ViewModels的任何更改

public class BaseNotifier : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}

以下是我们更新后的型号。注意BaseNotifier中定义的OnPropertyChanged的使用,因为这将使用新的服务器名称更新视图

public class Server : BaseNotifier
{
private string _serverName;
public string ServerName
{
get { return _serverName; }
set
{
_serverName = value;
OnPropertyChanged();
}
}
private int _serverID;
public int ServerID
{
get { return _serverID; }
set
{
_serverID = value;
OnPropertyChanged();
}
}
}

这就是ViewModel现在的样子。对于ViewModels,请使用ObservableCollection而不是List,以允许在插入数据时自动更新视图。您还将注意到,该代码在SelectedServer和EditedServerName中都检查null,这应该可以处理您最初的问题

public class MainViewModel : BaseNotifier
{
private string editedServerName;
private Server selectedServer = null;
public ObservableCollection<Server> Servers { get; set; }
public Server SelectedServer
{
get { return selectedServer; }
set
{
if (value != null)
{
selectedServer = value;
OnPropertyChanged();
}
}
}
public string EditedServerName
{
get { return editedServerName; }
set
{
editedServerName = value;
if (SelectedServer != null)
{
SelectedServer.ServerName = value;
}
OnPropertyChanged();
}
}
public MainViewModel()
{
Servers = new ObservableCollection<Server>();
Servers.Add(new Server { ServerID = 0, ServerName = "Local" });
Servers.Add(new Server { ServerID = 1, ServerName = "Remote" });
}
}

最新更新