我有一个带有2个按钮的自定义视图 - 一个在左边,一个在右边。
我希望有一个可绑定的属性来指示每个按钮将调用哪个函数,但我要调用的函数是在原始内容页面中,而不是自定义控件。
我知道你不能作为可绑定属性的空白,所以我不知道如何实现这一点。
这是我的自定义控件xaml:
<?xml version="1.0" encoding="UTF-8"?>
<RelativeLayout xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="EngineerApp.HeaderBar" HeightRequest="50">
<BoxView x:Name="banner" BackgroundColor="#edeff2"
RelativeLayout.WidthConstraint="{ ConstraintExpression
Type=RelativeToParent,
Property=Width,
Factor=1 }"
RelativeLayout.HeightConstraint="{ ConstraintExpression
Type=RelativeToParent,
Property=Height,
Factor=1 }">
</BoxView>
<Button
Text="Left"
x:Name="btnLeft"
Style="{StaticResource headerBarButton}"
RelativeLayout.WidthConstraint="{ ConstraintExpression
Type=RelativeToView,
ElementName=banner,
Property=Width,
Factor=0.5 }"
RelativeLayout.HeightConstraint="{ ConstraintExpression
Type=RelativeToView,
ElementName=banner,
Property=Height,
Factor=1 }"
>
</Button>
<Button
Text="Right"
Style="{StaticResource headerBarButton}"
RelativeLayout.XConstraint="{ ConstraintExpression
Type=RelativeToView,
ElementName=banner,
Property=Width,
Factor=0.5,
Constant=1
}"
RelativeLayout.WidthConstraint="{ ConstraintExpression
Type=RelativeToView,
ElementName=banner,
Property=Width,
Factor=0.5 }"
RelativeLayout.HeightConstraint="{ ConstraintExpression
Type=RelativeToView,
ElementName=banner,
Property=Height,
Factor=1 }"
>
</Button>
</RelativeLayout>
这是后端代码:
using System;
using System.Collections.Generic;
using System.Windows.Input;
using Xamarin.Forms;
namespace EngineerApp
{
public partial class HeaderBar : RelativeLayout
{
public HeaderBar()
{
InitializeComponent();
}
}
}
最后,我通过
包含自定义新内容<local:HeaderBar></local:HeaderBar>
如何将2个按钮单击事件中的每一个绑定到我的内容页面中的方法?
答案 0 :(得分:2)
您可以在自定义控件中公开几个事件。
<强>步骤:强>
在自定义HeaderBar
控件中创建2个事件。
public event EventHandler RightButtonClickEvent;
public event EventHandler LeftButtonClickEvent;
在XAML中分配Clicked
个事件处理程序,并在其中调用这些事件
void RightButton_Clicked(object sender, EventArgs e)
{
RightButtonClickEvent?.Invoke(sender, e);
}
void LeftButton_Clicked(object sender, EventArgs e)
{
LeftButtonClickEvent?.Invoke(sender, e);
}
使用ContentPage
<local:HeaderBar
RightButtonClickEvent="OnRightButtonClick"
LeftButtonClickEvent="OnLeftButtonClick" />
示例代码 - HeaderBar.xaml.cs
public partial class HeaderBar : RelativeLayout
{
public HeaderBar()
{
InitializeComponent();
}
public event EventHandler RightButtonClickEvent;
public event EventHandler LeftButtonClickEvent;
void RightButton_Clicked(object sender, EventArgs e)
{
RightButtonClickEvent?.Invoke(sender, e);
}
void LeftButton_Clicked(object sender, EventArgs e)
{
LeftButtonClickEvent?.Invoke(sender, e);
}
}
更新了示例代码 - HeaderBar.xaml
<?xml version="1.0" encoding="UTF-8"?>
<RelativeLayout xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="EngineerApp.HeaderBar" HeightRequest="50">
<BoxView x:Name="banner" BackgroundColor="#edeff2"
RelativeLayout.WidthConstraint="{ ConstraintExpression
Type=RelativeToParent,
Property=Width,
Factor=1 }"
RelativeLayout.HeightConstraint="{ ConstraintExpression
Type=RelativeToParent,
Property=Height,
Factor=1 }">
</BoxView>
<Button
Text="Left"
x:Name="btnLeft"
Clicked="LeftButton_Clicked"
Style="{StaticResource headerBarButton}"
RelativeLayout.WidthConstraint="{ ConstraintExpression
Type=RelativeToView,
ElementName=banner,
Property=Width,
Factor=0.5 }"
RelativeLayout.HeightConstraint="{ ConstraintExpression
Type=RelativeToView,
ElementName=banner,
Property=Height,
Factor=1 }"
>
</Button>
<Button
Text="Right"
x:Name="btnRight"
Clicked="RightButton_Clicked"
Style="{StaticResource headerBarButton}"
RelativeLayout.XConstraint="{ ConstraintExpression
Type=RelativeToView,
ElementName=banner,
Property=Width,
Factor=0.5,
Constant=1
}"
RelativeLayout.WidthConstraint="{ ConstraintExpression
Type=RelativeToView,
ElementName=banner,
Property=Width,
Factor=0.5 }"
RelativeLayout.HeightConstraint="{ ConstraintExpression
Type=RelativeToView,
ElementName=banner,
Property=Height,
Factor=1 }"
>
</Button>
</RelativeLayout>
示例代码 - MyContentPage.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"
xmlns:local="clr-namespace:EngineerApp"
x:Class="EngineerApp.MyContentPage">
<local:HeaderBar
RightButtonClickEvent="OnRightButtonClick"
LeftButtonClickEvent="OnLeftButtonClick" />
</ContentPage>
示例代码 - MyContentPage.xaml.cs
public partial class MyContentPage : ContentPage
{
public MyContentPage()
{
InitializeComponent();
}
void OnRightButtonClick(object sender, EventArgs e)
{
//handle right-button click here
}
void OnLeftButtonClick(object sender, EventArgs e)
{
//handle left-button click here
}
}
将两个命令公开为可绑定属性(后者将绑定到内部按钮控件)。然后,您可以将这些新命令绑定到ContentPage
的{{1}}
示例代码 - Header.xaml.cs
ViewModel
示例代码 - MyContentPage.xaml
public partial class HeaderBar : RelativeLayout
{
public HeaderBar()
{
InitializeComponent();
//create binding between parent control and child controls
btnLeft.SetBinding(Button.CommandProperty, new Binding(nameof(LeftButtonCommand), source: this));
btnRight.SetBinding(Button.CommandProperty, new Binding(nameof(RightButtonCommand), source: this));
}
public static readonly BindableProperty LeftButtonCommandProperty =
BindableProperty.Create(
"ILeftButtonCommand", typeof(ICommand), typeof(HeaderBar),
defaultValue: null);
public ICommand LeftButtonCommand
{
get { return (ICommand)GetValue(LeftButtonCommandProperty); }
set { SetValue(LeftButtonCommandProperty, value); }
}
public static readonly BindableProperty RightButtonCommandProperty =
BindableProperty.Create(
"RightButtonCommand", typeof(ICommand), typeof(HeaderBar),
defaultValue: null);
public ICommand RightButtonCommand
{
get { return (ICommand)GetValue(RightButtonCommandProperty); }
set { SetValue(RightButtonCommandProperty, value); }
}
}
示例代码 - MyContentPageViewModel.cs
<?xml version="1.0" encoding="utf-8"?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:EngineerApp"
x:Class="EngineerApp.MyContentPage">
<local:HeaderBar
LeftButtonCommand="{Binding LeftClickCommand}"
RightButtonCommand="{Binding RightClickCommand}" />
</ContentPage>
答案 1 :(得分:0)
我有类似的问题。 我创建了一个CalculatorPage.xaml(我的自定义控件)和一个链接的CalculatorViewModel。
对于我的自定义控件中的每个按钮:
<Button Grid.Row="0" Grid.Column="1" Font="Large" Command="{Binding Calculator.KeyPressCommand}" CommandParameter="Eight" Text="8" />
在上面的示例中,CalculatorViewModel中存在“KeyPressCommand”。但“计算器”不存在。
我创建了一个新的MainView(我的主视图)和相应的MainViewModel。
正如您所做的那样,我将自定义控件包含在我的XAML中,如下所示:
<common:CalculatorView></common:CalculatorView>
在MainViewModel中,我有一个属性
public CalculatorViewModel Calculator { get; private set; } = new CalculatorViewModel();
可能有一个更好的解决方案,你定义自定义控件的BindingContext但我的解决方案工作正常