Новичок в .NET MAUI и MVVM. Я видел другие примеры для этого, но мой не будет работать. Когда я запускаю код, он показывает строку PlayProperty в PlayMCanvas как нулевую. Я не знаю, как получить данные на холсте.
ВМ
public class ShowViewModel
{
public string TheString {get;set; }
public ShowViewModel()
{
TheString = "test";
}
}
Посмотреть программный код
public partial class ShowPlay : ContentPage
{
public ShowViewModel TheVM;
public ShowPlay()
{
InitializeComponent();
TheVM = new ShowViewModel();
TheVM.TheString = "test2";
BindingContext = TheVM;
}
}
XAML-представление
<?xml version = "1.0" encoding = "utf-8" ?>
<ContentPage xmlns = "http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x = "http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:drawables = "clr-namespace:PlayMApp.Drawables"
xmlns:local = "clr-namespace:PlayMApp"
x:Class = "PlayMApp.ShowPlay"
x:DataType = "local:ShowViewModel"
Title = "Show Play">
<VerticalStackLayout>
<Label
Text = "Welcome to .NET MAUI!"
VerticalOptions = "Center"
HorizontalOptions = "Center" />
<Button
Text = "Add Motion"
Clicked = "AddMotion"
VerticalOptions = "Start"
HorizontalOptions = "Center"></Button>
<GraphicsView HeightRequest = "300"
WidthRequest = "400">
<GraphicsView.Drawable>
<drawables:PlayMCanvas Play = "{ Binding TheString }" />
</GraphicsView.Drawable>
</GraphicsView>
</VerticalStackLayout>
</ContentPage>
PlayMCanvas
public class PlayMCanvas : GraphicsView, IDrawable
{
public PlayMCanvas()
{
}
public string Play
{
get => (string)GetValue(PlayProperty);
set => SetValue(PlayProperty, value);
}
public static BindableProperty PlayProperty = BindableProperty.Create(nameof(Play), typeof(string), typeof(PlayMCanvas));
public void Draw(ICanvas canvas, RectF dirtyRect)
{
canvas.StrokeColor = Colors.Red;
canvas.StrokeSize = 6;
canvas.DrawLine(10, 10, 90, 100);
canvas.DrawString(Play,40,30,HorizontalAlignment.Left);
}
}
Когда я дохожу до последней строки (DrawString), я думаю, что Play должен быть «test2», но это null
Я пытался внести изменения в код, чтобы настроить то, что отправляется. Если я отправлю просто литеральную строку через <drawables:PlayMCanvas Play = "test" />, это сработает, но не с привязкой
В данном случае это не имеет значения, так как он назначает свойства виртуальной машины до того, как устанавливает BindingContext. OP, у вас действительно есть все эти пробелы в выражении привязки?
@Jason Джейсон Ах да, вы правы, но никакие изменения не будут распространяться в любом случае. Действительно, пробел не допускается. Должно быть Play = "{Binding TheString}".
Я добавлю к вышесказанному: при запуске появляется ли на панели вывода VS предупреждение о том, что атрибут Play имеет неправильное значение? Это будет ключом к тому, что нужно изменить, как описано выше.
Я попытался удалить пробел, добавив INotifyPropertyChanged (и добавил «общедоступное событие PropertyChangedEventHandler PropertyChanged;» в VM) и переместив назначение после BindingContext и Play по-прежнему равно нулю. Если ничего другого, не должен ли он установить для TheString значение «test» в конструкторе ShowViewModel и связать его с этим значением, даже если не происходит никакого изменения свойства? Он показывает Play как null, даже если я удаляю "TheVM.TheString = "test2";" линия
Я понял это, увидел другой пример, когда кто-то очень точно указал компонент, к которому они были привязаны, и последовал этому.
Добавлено x:Name к PlayMCanvas, как показано ниже:
<drawables:PlayMCanvas x:Name = "PlayMCan" Play = "{Binding TheString}" />
Изменено на это в коде:
PlayMCan.BindingContext = TheVM;
И теперь привязка вроде работает.
Спасибо за комментарии!
Ваша ViewModel должна либо реализовать интерфейс INotifyPropertyChanged, либо наследоваться от базового класса, который делает, например. ObservableObject из набора инструментов сообщества MVVM. В противном случае никакие события PropertyChanged не возникают и, следовательно, никакие изменения свойств не распространяются на представление.