Xamarin.forms 更改代码隐藏中的属性不会更新视图
当我更改作为模型对象的属性时,视图不会更新,除非我重新指定绑定上下文。我没有使用mvvm,所以没有视图模型Xamarin.forms 更改代码隐藏中的属性不会更新视图,xamarin.forms,data-binding,Xamarin.forms,Data Binding,当我更改作为模型对象的属性时,视图不会更新,除非我重新指定绑定上下文。我没有使用mvvm,所以没有视图模型 public partial class MainPage : ContentPage { private MySource _myCurrentSource = new MySource("yolor"); public MySource MyCurrentSource { get { return _myCurrentSo
public partial class MainPage : ContentPage
{
private MySource _myCurrentSource = new MySource("yolor");
public MySource MyCurrentSource {
get { return _myCurrentSource; }
set {_myCurrentSource = value; }
}
public MainPage()
{
InitializeComponent();
MyCurrentSource = _myCurrentSource;
MainStack.BindingContext = MyCurrentSource;
label.SetBinding(Label.TextProperty, new Binding("SourceString"));
}
private void Button_Clicked(object sender, EventArgs e)
{
MyCurrentSource = new MySource("new string");
//property changed
MainStack.BindingContext = MyCurrentSource;
}
}
我想摆脱:MainStack.BindingContext=MyCurrentSource代码>
这就是我的xaml的样子
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="DataBindingPlayGround.MainPage">
<StackLayout Padding="10, 0" x:Name="MainStack" HorizontalOptions="Center"
VerticalOptions="CenterAndExpand">
<Label x:Name="label" Text="TEXT" FontSize="48" />
<Button Text="Change" Clicked="Button_Clicked"/>
</StackLayout>
</ContentPage>
修改MySource类,如下所示进行尝试:
public class MySource : INotifyPropertyChanged
{
public MySource(string str)
{
sourceString = str;
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
private string sourceString;
public double SourceString
{
set
{
if (sourceString != value)
{
sourceString = value;
OnPropertyChanged("SourceString");
}
}
get
{
return sourceString;
}
}
}
========================================更新=================================
虽然不了解应用程序的逻辑,但如果您想使MyCurrentSource
正常工作。您还需要使用INotifyPropertyChanged
:
public partial class MainPage : ContentPage ,INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
private MySource _myCurrentSource;
public MySource MyCurrentSource
{
set
{
if (_myCurrentSource != value)
{
_myCurrentSource = value;
OnPropertyChanged("MyCurrentSource");
}
}
get
{
return _myCurrentSource;
}
}
public MainPage()
{
InitializeComponent();
_myCurrentSource = new MySource("yolor");
//MyCurrentSource = _myCurrentSource;
MainStack.BindingContext = _myCurrentSource ;
label.SetBinding(Label.TextProperty, new Binding("SourceString"));
}
private void Button_Clicked(object sender, EventArgs e)
{
_myCurrentSource = new MySource("new string");
//property changed
MainStack.BindingContext = _myCurrentSource;
}
}
或当绑定上下文时,您可以直接设置新模型
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
MainStack.BindingContext = new MySource("yolor");
label.SetBinding(Label.TextProperty, new Binding("SourceString"));
}
private void Button_Clicked(object sender, EventArgs e)
{
//property changed
MainStack.BindingContext = new MySource("new string");
}
}
如果有人有类似的情况,这对我来说终于奏效了:
来源类别如下:
public class FirstSource
{
public string sourceString;
public string SourceString { get; set; }
public int SourceOneProp2 { get; set; }
public FirstSource(string str, int num)
{
SourceString = str;
SourceOneProp2 = num;
}
}
public class SecondSource
{
public string ExampleField { get; set; }
public int SourceTwoProp2 { get; set; }
public SecondSource(string exampleField, int num)
{
ExampleField = exampleField;
SourceTwoProp2 = num;
}
}
ViewModel(决定用于简化任务)
代码隐藏:
public partial class MainPage : ContentPage
{
int counter = 0;
private MainPageViewModel ViewModel
{
get { return BindingContext as MainPageViewModel; }
set { BindingContext = value; }
}
public MainPage()
{
InitializeComponent();
ViewModel = new MainPageViewModel();
ViewModel.SourceOne = new FirstSource("init1", 10);
ViewModel.SourceTwo = new SecondSource("init2", 20);
}
private void Button_Clicked(object sender, EventArgs e)
{
counter += 1;
ViewModel.SourceOne = new FirstSource("Changed1", 100+counter);
}
private void Button_Clicked_1(object sender, EventArgs e)
{
counter += 1;
ViewModel.SourceTwo = new SecondSource("Changed2", 200+counter);
}
}
XAML/UI
<StackLayout Padding="10, 0" x:Name="MainStack" HorizontalOptions="Center" VerticalOptions="Start">
<Label x:Name="label" Text="{Binding Path=SourceOne.SourceString}" FontSize="48" />
<Label Text="{Binding Path=SourceOne.SourceOneProp2}" />
<Button Text="Change" Clicked="Button_Clicked"/>
<StackLayout Padding="10, 0" x:Name="SecondStack">
<Label x:Name="secondLabel" Text="{Binding Path=SourceTwo.ExampleField}" FontSize="48" />
<Label Text="{Binding Path=SourceTwo.SourceTwoProp2}" />
<Button Text="Change" Clicked="Button_Clicked_1"/>
</StackLayout>
</StackLayout>
您需要使用INotifyPropertyChanged。如果我这样做MyCurrentSource.SourceString=“string changed”
,我现在就添加了提到的更改。但我想要的,但仍然没有实现的是:MyCurrentSource=newmySource(“新字符串”)
Note:MyCurrentSource是代码隐藏中的一个属性,它由以下内容支持:private MySource\u MyCurrentSource=newmySource(“yolor”)代码>我对更改对象的属性不感兴趣,我想在代码隐藏中为我的属性指定一个新对象,实际上我从一个具有多个字段的通信通道接收到两个对象。我需要相应地更新UI。因此,我想将这些新对象指定给代码隐藏中的两个属性。在UI中,两个不同的堆栈布局将这两个属性作为其绑定上下文。因为ContentPage
中存在错误。您没有理解我使用INotifyPropertyChanged
的共享回复。如果您可以将它用于MyCurrentSource
,它也会起作用。这很有帮助。虽然它在codebehind i.2(实现接口的主页面)中不起作用,但使用视图模型类尝试了同样的方法,效果非常好。我添加了结果代码作为答案。谢谢你。@UmerMehmood很高兴你解决了这个问题。记得在可能的时候标出答案。
public partial class MainPage : ContentPage
{
int counter = 0;
private MainPageViewModel ViewModel
{
get { return BindingContext as MainPageViewModel; }
set { BindingContext = value; }
}
public MainPage()
{
InitializeComponent();
ViewModel = new MainPageViewModel();
ViewModel.SourceOne = new FirstSource("init1", 10);
ViewModel.SourceTwo = new SecondSource("init2", 20);
}
private void Button_Clicked(object sender, EventArgs e)
{
counter += 1;
ViewModel.SourceOne = new FirstSource("Changed1", 100+counter);
}
private void Button_Clicked_1(object sender, EventArgs e)
{
counter += 1;
ViewModel.SourceTwo = new SecondSource("Changed2", 200+counter);
}
}
<StackLayout Padding="10, 0" x:Name="MainStack" HorizontalOptions="Center" VerticalOptions="Start">
<Label x:Name="label" Text="{Binding Path=SourceOne.SourceString}" FontSize="48" />
<Label Text="{Binding Path=SourceOne.SourceOneProp2}" />
<Button Text="Change" Clicked="Button_Clicked"/>
<StackLayout Padding="10, 0" x:Name="SecondStack">
<Label x:Name="secondLabel" Text="{Binding Path=SourceTwo.ExampleField}" FontSize="48" />
<Label Text="{Binding Path=SourceTwo.SourceTwoProp2}" />
<Button Text="Change" Clicked="Button_Clicked_1"/>
</StackLayout>
</StackLayout>