ObservableCollection
запускает изменения при каждом изменении элементов коллекции. List
нет. Вот в чем причина.
DataBinding является ленивым. Если вы не сообщите своему мнению, что что-то изменилось, оно не будет обновлять. Под капотами WPF DataBinding регистрирует уведомления об изменениях, так что ваша ViewModel может отображать представление, когда оно изменилось. Он делает это с интерфейсами, такими как INotifyPropertyChanged
и INotifyCollectionChanged
.
ObservableCollection
реализует интерфейс INotifyCollectionChanged
. Этот интерфейс определяет событие CollectionChanged
, которое ваш вид в основном прикрепляет к своему собственному обработчику событий. Этот обработчик обновит представление, когда событие будет собрано коллекцией.
Я еще об этом подумал, и ты можешь игнорировать мой предыдущий ответ. Это решение является излишне сложным. Я получил возможность сосредоточиться на возвращении &mut Self
из put
, хотя об этом вообще не просили. Вы можете просто вернуть &mut RequestInfo
из вашего метода put
, и все в порядке. Единственная цена, которую вы платите, это то, что вы больше не можете иметь реализацию по умолчанию для put
.
pub trait RequestInfo {
fn put(self: &mut Self, string: String) -> &mut dyn RequestInfo;
}
struct LoggedOut {}
impl RequestInfo for LoggedOut {
fn put(self: &mut Self, string: String) -> &mut dyn RequestInfo {
self
}
}
struct LoggedIn {
output: Vec<String>,
}
impl LoggedIn {
fn new() -> LoggedIn {
LoggedIn { output: Vec::new() }
}
}
impl RequestInfo for LoggedIn {
fn put(self: &mut Self, string: String) -> &mut dyn RequestInfo {
self.output.push(string);
self
}
}
fn get(flag: bool) -> Box<dyn RequestInfo> {
if flag {Box::new(LoggedIn::new())} else {Box::new(LoggedOut{})}
}
fn main() {
let mut info = get(false);
info.put("abc".to_string()).put("def".to_string());
}
А теперь перейдем к последнему шагу: вы заметили, что черты с методами, которые возвращают Self
, не могут использоваться в качестве объектов черт . Эта ссылка имеет решение вашей проблемы: пометьте этот метод с помощью where Self: Sized
, чтобы он не появился на вашем объекте черты. Но тогда вы не можете связывать свои объекты с чертами. Это может быть решено путем реализации метода в Box<dyn RequestInfo>
, который является не объектом-признаком, а Box
. Итак, собрав все это вместе:
pub trait RequestInfo {
fn logged_in(&self) -> bool;
fn put(&mut self, string: String) -> &mut Self
where Self: Sized {
self.put_internal(string);
self
}
fn put_internal(&mut self, string: String) {}
}
impl RequestInfo for Box<dyn RequestInfo> {
fn logged_in(&self) -> bool {
self.as_ref().logged_in()
}
}
struct LoggedOut {}
impl RequestInfo for LoggedOut {
fn logged_in(&self) -> bool {false}
}
struct LoggedIn {output: Vec<String>}
impl LoggedIn {
fn new() -> LoggedIn {
LoggedIn { output: Vec::new() }
}
}
impl RequestInfo for LoggedIn {
fn logged_in(&self) -> bool {true}
fn put_internal(&mut self, string: String) {
self.output.push(string);
}
}
fn get(flag: bool) -> Box<dyn RequestInfo> {
if flag {Box::new(LoggedIn::new())} else {Box::new(LoggedOut{})}
}
fn main() {
let mut info = get(true);
info.put("abc".to_string()).put("def".to_string());
}
Вам придется решить, стоит ли все это для некоторой цепочки.