我有一个绑定(bind):
public static readonly BindableProperty
EntryWidthProperty = BindableProperty.Create(nameof(EntryWidth),
typeof(int),
typeof(SingleEntryGrid), 150, BindingMode.TwoWay);
public int EntryWidth {
get => (int)GetValue(EntryWidthProperty);
set => SetValue(EntryWidthProperty, value);
}
和这个 C# 代码:var column3 = new ColumnDefinition()
{
Width = new GridLength(???, GridUnitType.Absolute)
};
请注意, GridLength 是一个结构:https://docs.microsoft.com/en-us/dotnet/api/xamarin.forms.gridlength?view=xamarin-forms
有谁知道我如何绑定(bind)到标有???
有关更多解释,这是我正在尝试做的:
我希望能够设置输入框框架的宽度。在这个例子中,它们的宽度都相同。
最佳答案
你不能那样做。正如您所说, GridLength 是一个结构,但可能比这更重要的是,您设置的 Value 只是一个带有 getter 的公共(public)属性(它甚至不是 BindableProperty )。这意味着你只能通过一个方法来设置它,在这种情况下它恰好是 GridLength
ctor 本身。您可以检查 GridLength here 的代码。
你可以做的是两件事之一 - 要么保留所有你需要的宽度为 Auto
,要么继承 Grid
类。
如果您决定采用第一种方法,则不必编写任何额外的代码。根据 Rows and columns 文档:
Auto
– the row height or column width is autosized based on the cell contents (Auto in XAML).
乍一看,这应该可以解决问题,因为所有宽度都将采用子项宽度的最大值(在本例中为 150)。不幸的是,这给
Grid
的渲染增加了一些开销,而且在任何情况下都不小。如果你稍微往下看文档,你会看到一个红色警告,你应该:Try to ensure that as few rows and columns as possible are set to
Auto
size. Each auto-sized row or column will cause the layout engine to perform additional layout calculations. Instead, use fixed size rows and columns if possible. Alternatively, set rows and columns to occupy a proportional amount of space with the GridUnitType.Star enumeration value.
这也可以在 Optimize layout performance 中再次看到,如果您还没有阅读,我强烈建议您阅读。
话虽如此,您可以采用第二种方法。它背后的想法是在你的新类中有一个可绑定(bind)的属性,在设置这个属性时,你将更新
ColumnDefinition
的 Width
属性。不幸的是,这必须“手动”完成。这是您的属性的示例(我已将其类型更改为 double
以与列的 Width
属性相同):public partial class MainPage
{
private ColumnDefinition column3;
public static readonly BindableProperty EntryWidthProperty = BindableProperty.Create(nameof(EntryWidth), typeof(double),
typeof(SingleEntryGrid), (double) 150, BindingMode.TwoWay);
public double EntryWidth
{
get => (double) GetValue(EntryWidthProperty);
set
{
SetValue(EntryWidthProperty, value);
if (column3 != null)
{
column3.Width = value;
}
}
}
public MainPage()
{
InitializeComponent();
var grid = new SingleEntryGrid
{
ColumnDefinitions = new ColumnDefinitionCollection()
};
// TODO: Other columns
column3 = new ColumnDefinition
{
// The default value for EntryWidth
Width = new GridLength(150, GridUnitType.Absolute)
};
grid.ColumnDefinitions.Add(column3);
// The rest of your code
Content = grid;
}
}
正如您在代码中看到的,第三列最初设置为 Absolute
宽度 150(EntryWidth
的默认值)。在 EntryWidth
属性的值发生一些变化后,setter 将自动更改第三列。当然,这不是最优雅的解决方案,因为它总是只更新第三列,但您可以从这里继续。由于我不知道究竟是什么情况以及它将用于什么,我不能说什么是最佳选择 - 为每列创建更多属性,或者使用键值创建它们的列表(甚至可能是一个单独的类)绑定(bind)到它们 - 这样你就可以为每一列动态设置它。
附言而且,如果您从一开始就知道您的宽度,或者您只有 1 列需要
Auto
,请使用传统方法。尽量不要使一切过于复杂,并相应地设置您的列定义。编辑:根据更新的问题,我们应该采取另一种方法。从图像中我无法完全理解整体模板是什么,但我们在这里有 2 个选项:
但是,无论我们选择什么,所有 View 的列都将具有相同的宽度。在这种情况下,我可以建议所有输入的宽度也相同(将它们的
HorizontalOptions
设置为 StartAndExpand
或 FillAndExpand
)。而不是明确设置它们的宽度,您可以尝试将列的宽度设置为(取决于您其他列的配置):Star
(*) 或者您不希望该列与其他星星成比例 - 将其宽度设置为 Star
。这样,该列将采用剩余的任何内容。 Absolute
值。 您不应该尝试动态更改列 - 这不会是一个好的 UX,您还必须添加检查何时停止。
总而言之,将第三列(包含条目)设置为
Star
或 Absolute
。如果您的其他一列设置为 Auto
并且另一列具有 Absolute
宽度,则您可以轻松地将第三列设置为 Star
,这将占用与剩余宽度一样多的宽度)。如果您想每次都采用“那么多”的宽度(将其与您希望可见的最大条目/符号一起使用),则应使用 Absolute
。
关于c# - 如何在 C# 中绑定(bind)到 Grid ColumnDefinition Width,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62473192/