一个按钮上可以有多个绑定吗?

时间:2019-03-28 22:57:22

标签: xaml xamarin.forms binding

我试图在列表视图中的一个按钮上具有命令绑定和IsVisible绑定。如果按钮中有绑定上下文,则命令绑定将起作用,而IsVisible绑定将不起作用。如果删除绑定上下文,则IsVisible绑定将起作用,但Command绑定将不起作用。有没有关于如何纠正这种情况的建议。

<Button BindingContext="{Binding Source={x:Reference icaoDownloads}, 
        Path=BindingContext}"
        Command="{Binding DownloadCommand}"
        CommandParameter="{Binding Source={x:Reference Item}, 
                                          Path=BindingContext}"
        HorizontalOptions="CenterAndExpand"
        VerticalOptions="Center"
        BackgroundColor="Black"
        TextColor="WhiteSmoke"
        Grid.Column="1"
        Text="  Update  "
        BorderColor="DarkSlateGray"
        BorderRadius="5"
        BorderWidth="2"
        Margin="2"
        IsVisible="{Binding IsDownloadable}" />

我有一个从数据库集中创建的列表。我试图仅在数据库具有可用更新时显示按钮。因此,我想使该按钮仅在更新时出现,单击该按钮并将数据下载到数据库,然后使该按钮不可见。

2 个答案:

答案 0 :(得分:0)

很遗憾,xaml不支持多个绑定。

如果按钮位于ListView中,则

BindingContext="{Binding Source={x:Reference icaoDownloads}, Path=BindingContext}"

应删除表单按钮。

解决方案之一:尝试使用以下代码:

<Button
       Command="{Binding BindingContext.DownloadCommand, Source={x:Reference icaoDownloads}}"
        CommandParameter="{Binding Source={x:Reference Item},Path=BindingContext}"
        HorizontalOptions="CenterAndExpand"
        VerticalOptions="Center"
        BackgroundColor="Black"
        TextColor="WhiteSmoke"
        Grid.Column="1"
        Text="  Update  "
        BorderColor="DarkSlateGray"
        BorderRadius="5"
        BorderWidth="2"
        Margin="2"
        IsVisible="{Binding IsDownloadable}" />

解决方案二:如果 Xaml 代码如下:

<ListView x:Name="listviewbig" ItemsSource="{Binding Monkeys}" 
                HasUnevenRows="true" 
                ItemTapped="OnListViewItemTapped"
                ItemSelected="OnListViewItemSelected">
  <ListView.ItemTemplate>
    <DataTemplate>
        <ViewCell>
            <Grid Padding="10">
                <Grid.RowDefinitions>
                    <RowDefinition Height="Auto" />
                </Grid.RowDefinitions>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="10" />
                    <ColumnDefinition Width="100" />
                </Grid.ColumnDefinitions>
                <Label Grid.Row="0" 
                Grid.Column="0" 
                Text="{Binding Location}"
                VerticalOptions="End" 
                Style="{DynamicResource SubtitleTextStyle}" />
                <Button Grid.Row="0"
                    Grid.Column="1"
                    Text="Click"
                    HorizontalOptions="End"
                    IsVisible="{Binding IsDownloadable}"
                    Clicked="OnClicked"
                    Command="{Binding DownloadCommand}"
                    CommandParameter="2"/>
                <ProgressBar Grid.Row="1" 
                Grid.Column="3" x:Name="progressBar" 
    Progress="{Binding CurrentProgress,Mode=OneWayToSource}" 
    PropertyChanged="ProgressBar_PropertyChanged"/>
            </Grid>
        </ViewCell>
    </DataTemplate>
  </ListView.ItemTemplate>
</ListView>

MonkeysViewModel.cs

    class MonkeysViewModel
    {
        public IList<Monkey> Monkeys { get; private set; }

        private async void ShowCustomerInfo(object obj)
        {
             Console.WriteLine("true" + obj );
        }

        public MonkeysViewModel()
            {


                Monkeys = new List<Monkey>();
                //f = new F[5];
                Monkeys.Add(new Monkey
                {
                    Name = "Baboon",
                    Location = "Africa & Asia",
                    CommandShowInfo = new Command(ShowCustomerInfo),
                    IsDownloadable = true
                });
                ...
                }
            }
    }

Monkey.cs

public class Monkey : INotifyPropertyChanged
{
    public string Name { set; get; }
    public string Location { get; set; }

    public System.Windows.Input.ICommand CommandShowInfo { get; set; }

    private bool isDownloadable = true;
    public bool IsDownloadable
    {
        set
        {
            if (isDownloadable != value)
            {
                isDownloadable = value;
                OnPropertyChanged("IsDownloadable");
            }
        }
        get
        {
            return isDownloadable;
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    private void OnPropertyChanged([CallerMemberName] String propertyName = "")
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

此处的ListView ContentPage:BindingContext = new MonkeysViewModel();

和“测试按钮”单击方法:

void OnClicked(Object sender, MyEventArgs args)
{
    Button btn = sender as Button;
    var monkey = btn.BindingContext as Monkey;
    monkey.IsDownloadable = false;
}

也许是绑定模型使用不正确。

答案 1 :(得分:0)

这是我的解决方案:

<Button CommandParameter="{Binding .}"
                                            Command="{Binding BindingContext.DownloadCommand, Source={x:Reference TestIcaoContent}}"
                                            HorizontalOptions="CenterAndExpand"
                                            VerticalOptions="Center"
                                            BackgroundColor="Black"
                                            TextColor="WhiteSmoke"
                                            Grid.Column="1"
                                            Text="  Update  "
                                            BorderColor="DarkSlateGray"
                                            BorderRadius="5"
                                            BorderWidth="2"
                                            Margin="2"
                                            IsVisible="{Binding Source={x:Reference Item}, Path=BindingContext.IsDownloadable}" />

这解决了我的问题,让我将列表项的值传递给了视图模型。

这是我的视图模型的构造函数:

public ICommand NavCommandCommand { get; private set; }
public INavigation Navigation { get; set; }
public ICommand DownloadCommand { get; private set; }

        public TestIcaoViewModel()
        {

            //DownloadCommand = new Command(Download);
            DownloadCommand = new Command((e) => { var item = (e as TestLandingViewModel); Download(item.IcaoCode); });

            NavCommandCommand = new Command((e) => { var item2 = (e as TestLandingViewModel); NavCommand(item2.IcaoCode); });
            LoadAirportData();   
        }