Xaml Can';t绑定IsBusy属性
我有一个带有以下代码的活动指示器的页面:Xaml Can';t绑定IsBusy属性,xaml,xamarin,xamarin.forms,Xaml,Xamarin,Xamarin.forms,我有一个带有以下代码的活动指示器的页面: <?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="MyApp.ClientSearch" Title="Sear
<?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="MyApp.ClientSearch" Title="Search">
<ContentPage.Content>
<StackLayout Orientation="Vertical">
<StackLayout.Children>
<SearchBar x:Name="txtSearchClient" TextChanged="OnTextChanged"></SearchBar>
<ActivityIndicator IsVisible="{Binding IsBusy}" IsRunning="{Binding IsBusy}" x:Name="indicadorCargando" />
<ListView x:Name="lstClients"></ListView>
</StackLayout.Children>
</StackLayout>
</ContentPage.Content>
</ContentPage>
如您所见,this.IsBusy
正在设置页面属性,因此尝试绑定到XAML中的该属性。不幸的是,它不起作用:
<ActivityIndicator IsVisible="{Binding IsBusy}" IsRunning="{Binding IsBusy}" x:Name="indicadorCargando" />
但我不想这样做,我想设置一个值而不是三个值。下面是我将如何重写它:
public class ClientSearch : ContentPage
{
public ClientSearch()
{
BindingContext = new ClientSearchViewModel();
var stack = new StackLayout();
var searchBar = new SearchBar();
searchBar.SetBinding<ClientSearchViewModel>(SearchBar.TextProperty, x => x.Text);
var actInd = new ActivityIndicator();
actInd.SetBinding<ClientSearchViewModel>(ActivityIndicator.IsVisibleProperty, x => x.IsBusy);
actInd.SetBinding<ClientSearchViewModel>(ActivityIndicator.IsRunningProperty, x => x.IsBusy);
var lv = new ListView
{
ItemTemplate = new DataTemplate(() =>
{
var txtCell = new TextCell();
txtCell.SetBinding<MyItemModel>(TextCell.TextProperty, x => x.Name_Ct);
txtCell.SetBinding<MyItemModel>(TextCell.TextProperty, x => x.Cod_Ct);
return txtCell;
})
};
lv.SetBinding<ClientSearchViewModel>(ListView.ItemsSourceProperty, x => x.items);
stack.Children.Add(searchBar);
stack.Children.Add(actInd);
stack.Children.Add(lv);
Content = stack;
}
}
public class ClientSearchViewModel : BaseViewModel
{
public string Text { get; set; }
public bool IsBusy { get; set; }
public IEnumerable<MyItemModel> items { get; set; }
protected override async void OnPropertyChanged(string propertyName = null)
{
if (propertyName != nameof(Text) || Text.Length < 3) return;
IsBusy = true;
items = await App.ClientsManager.GetTasksAsync(Text);
IsBusy = false;
}
}
[ImplementPropertyChanged]
public abstract class BaseViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
public类ClientSearch:ContentPage
{
公共客户端搜索()
{
BindingContext=new ClientSearchViewModel();
var stack=新的StackLayout();
var searchBar=新的searchBar();
searchBar.SetBinding(searchBar.TextProperty,x=>x.Text);
var actInd=新的ActivityIndicator();
actInd.SetBinding(ActivityIndicator.IsVisibleProperty,x=>x.IsBusy);
actInd.SetBinding(ActivityIndicator.isRunning属性,x=>x.IsBusy);
var lv=新列表视图
{
ItemTemplate=新数据模板(()=>
{
var txtCell=新的TextCell();
txtCell.SetBinding(TextCell.TextProperty,x=>x.Name\u Ct);
txtCell.SetBinding(TextCell.TextProperty,x=>x.Cod\u Ct);
返回txtCell;
})
};
lv.SetBinding(ListView.ItemsSourceProperty,x=>x.items);
stack.Children.Add(搜索栏);
stack.Children.Add(actInd);
stack.Children.Add(lv);
内容=堆栈;
}
}
公共类ClientSearchViewModel:BaseViewModel
{
公共字符串文本{get;set;}
公共bool正忙{get;set;}
公共IEnumerable项{get;set;}
受保护的重写异步无效OnPropertyChanged(字符串propertyName=null)
{
if(propertyName!=nameof(Text)| | Text.Length<3)返回;
IsBusy=true;
items=wait App.ClientsManager.GetTasksAsync(文本);
IsBusy=false;
}
}
[实现属性更改]
公共抽象类BaseViewModel:INotifyPropertyChanged
{
公共事件属性更改事件处理程序属性更改;
受保护的虚拟无效OnPropertyChanged([CallerMemberName]string propertyName=null)=>PropertyChanged?.Invoke(这是新的PropertyChangedEventArgs(propertyName));
}
您当然可以选择独立视图模型,这是个不错的主意。但是对于特定的问题,看起来您并没有在任何地方设置BindingContext,因此它不会得到您想要的IsBusy属性
我还没有尝试将控件的BindingContext设置为自身,但类似的方法应该可以工作:
<ActivityIndicator
IsVisible="{Binding IsBusy}"
IsRunning="{Binding IsBusy}"
x:Name="indicadorCargando"
BindingContext="{x:Reference indicadorCargando}" />
您需要为页面指定一个名称(x:name=“myPage”
),然后使用{binding Source={x:reference myPage},Path=IsBusy}
对ActivityIndicator的IsVisible
和IsRunning
值的引用来声明绑定。关于.< /p> 1的更多信息-为了清晰2,你应该考虑分离视图和视图模型——你应该在XAML 3中添加文本单元——你应该使用E文本。
public class ClientSearch : ContentPage
{
public ClientSearch()
{
BindingContext = new ClientSearchViewModel();
var stack = new StackLayout();
var searchBar = new SearchBar();
searchBar.SetBinding<ClientSearchViewModel>(SearchBar.TextProperty, x => x.Text);
var actInd = new ActivityIndicator();
actInd.SetBinding<ClientSearchViewModel>(ActivityIndicator.IsVisibleProperty, x => x.IsBusy);
actInd.SetBinding<ClientSearchViewModel>(ActivityIndicator.IsRunningProperty, x => x.IsBusy);
var lv = new ListView
{
ItemTemplate = new DataTemplate(() =>
{
var txtCell = new TextCell();
txtCell.SetBinding<MyItemModel>(TextCell.TextProperty, x => x.Name_Ct);
txtCell.SetBinding<MyItemModel>(TextCell.TextProperty, x => x.Cod_Ct);
return txtCell;
})
};
lv.SetBinding<ClientSearchViewModel>(ListView.ItemsSourceProperty, x => x.items);
stack.Children.Add(searchBar);
stack.Children.Add(actInd);
stack.Children.Add(lv);
Content = stack;
}
}
public class ClientSearchViewModel : BaseViewModel
{
public string Text { get; set; }
public bool IsBusy { get; set; }
public IEnumerable<MyItemModel> items { get; set; }
protected override async void OnPropertyChanged(string propertyName = null)
{
if (propertyName != nameof(Text) || Text.Length < 3) return;
IsBusy = true;
items = await App.ClientsManager.GetTasksAsync(Text);
IsBusy = false;
}
}
[ImplementPropertyChanged]
public abstract class BaseViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
<ActivityIndicator
IsVisible="{Binding IsBusy}"
IsRunning="{Binding IsBusy}"
x:Name="indicadorCargando"
BindingContext="{x:Reference indicadorCargando}" />