Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/google-app-engine/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Xamarin.forms 更改代码隐藏中的属性不会更新视图_Xamarin.forms_Data Binding - Fatal编程技术网

Xamarin.forms 更改代码隐藏中的属性不会更新视图

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

当我更改作为模型对象的属性时,视图不会更新,除非我重新指定绑定上下文。我没有使用mvvm,所以没有视图模型

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>