Существует ListBox ThreadBox
.
ThreadBox:
<ListBox x:Name="ThreadBox" SelectionChanged="ThreadBox_SelectionChanged" Grid.Column="1" ItemsSource="{Binding MThreadPV}" >
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Margin="2">
<CheckBox IsChecked="{Binding Path=Check}"></CheckBox>
<TextBlock FontSize="16" HorizontalAlignment="Center">
<Hyperlink TextDecorations="" NavigateUri="{Binding Path=Url}" Foreground="White" RequestNavigate="Hyperlink_RequestNavigate"><TextBlock FontSize="16" Text="{Binding Path=Thread}" HorizontalAlignment="Center"/></Hyperlink>
</TextBlock>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
DataTemplate привязан к классу CheckedItem
CheckedItem:
public class CheckedItem
{
private string thread;
private string url;
private bool check;
private int id;
public int ID
{
get { return id; }
set { id = value; }
}
public bool Check
{
get { return check; }
set { check = value; }
}
public string Thread
{
get { return thread; }
set
{
thread = value;
}
}
public string Url
{
get { return url; }
set
{
url = value;
}
}
}
Пытаюсь приплести к ThreadBox
ObservableCollection через MVVM.
Все делал по гайду https://habr.com/ru/post/338518/ , но по нулям.
Реализация модели:
class ThreadBoxModel : BindableBase
{
private readonly ObservableCollection<source.CheckedItem> _myValues = new ObservableCollection<source.CheckedItem>();
public readonly ReadOnlyObservableCollection<source.CheckedItem> MThreadValues;
public ThreadBoxModel()
{
MThreadValues = new ReadOnlyObservableCollection<source.CheckedItem>(_myValues);
}
public void AddValue(source.CheckedItem item)
{
_myValues.Add(item);
RaisePropertyChanged("T_Sum");
}
//проверка на валидность, удаление из коллекции и уведомление об изменении суммы
public void RemoveValue(int index)
{
//проверка на валидность удаления из коллекции - обязанность модели
if (index >= 0 && index < _myValues.Count) _myValues.RemoveAt(index);
RaisePropertyChanged("T_Sum");
}
public int T_Sum => MThreadValues.Count; //сумма
}
Реализация VM:
public class MyThreadsVM : BindableBase
{
readonly source.models.ThreadBoxModel _model = new source.models.ThreadBoxModel();
public MyThreadsVM()
{
//таким нехитрым способом мы пробрасываем изменившиеся свойства модели во View
_model.PropertyChanged += (s, e) => { RaisePropertyChanged(e.PropertyName); };
AddCommand = new DelegateCommand<source.CheckedItem>(str => {
_model.AddValue(str);
});
RemoveCommand = new DelegateCommand<int?>(i => {
if (i.HasValue) _model.RemoveValue(i.Value);
});
}
public DelegateCommand<source.CheckedItem> AddCommand { get; }
public DelegateCommand<int?> RemoveCommand { get; }
public int T_Sum => _model.T_Sum;
public ReadOnlyObservableCollection<source.CheckedItem> MThreadPV => _model.MThreadValues;
}
Использую ModernWindow
поэтому:
<mui:ModernWindow.DataContext>
<local:MyThreadsVM/>
</mui:ModernWindow.DataContext>
Элементы добавляю через (Сори за быдлокод):
private void ThreadBox_Update()
{
if (source.StaticData.cookies != null)
{
List<List<Dictionary<string, string>>> data = this.dark.GetMyThreads();
int iterator = 0;
source.models.ThreadBoxModel model = new source.models.ThreadBoxModel();
foreach (var list in data)
{
string url = list[0]["url"];
model.AddValue(new source.CheckedItem { Thread = list[0]["thread"], Url = $"{source.StaticData.head_url}{url}", ID = iterator, Check = false });
iterator++;
}
}
}
ThreadBox не обновляется. В чем может быть проблема?
В C# классы являются объектами и когда вы пишете new
создается новый объект. Если вы делаете привязку к объекту, то он не должен создаваться по новой, ибо WPF будет по прежнему ссылаться на тот, ранее созданный экземпляр объекта.
У вас в коде, привязанная коллекция инициализируется в конструкторе ThreadBoxModel
:
MThreadValues = new ReadOnlyObservableCollection<source.CheckedItem>(_myValues);
А саму модель ThreadBoxModel
вы инициализируете несколько раз:
В MyThreadsVM
:
readonly source.models.ThreadBoxModel _model = new source.models.ThreadBoxModel();
В методе ThreadBox_Update()
:
source.models.ThreadBoxModel model = new source.models.ThreadBoxModel();
В итоге вы получаете, что ваш интерфейс привязался к одной модели, а ваши данные добавились в совершенно другую модель.
Если вы хотите, что бы интерфейс знал, что ваша коллекция (или модель) переинициализировалась, то тут стоит его оповестить об этом. Для этого в WPF есть интерфейс INotifyPropertyChanged
, вам просто надо завести свойство, где в set
вы будете вызывать метод обновления от INPC
.
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
В компоненте Rigidbody2D есть такой параметр как Gravity Scale каким образом он влияет на глобальный компонент гравитации? Те
Можно ли обойтись без методов типа Update что бы заставить кнопку "назад" вызывать какой либо метод? Хотелось бы обойтись без постоянного вызова...
Суть в том, что у меня в базе данных есть как даты, так и десятичные числаОднако, при записывании в запрос числа с запятой он крашится с данным...
Есть класс Stack(стек реализованный на основе массива)(поля: массив stackArr и счётчик count)В нём реализован метод Pop(извлечение элемента из стека)