[英]How can I bind to a Grid ColumnDefinition Width in C#
我有一個綁定:
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://learn.microsoft.com/en-us/do.net/api/xamarin.forms.gridlength?view=xamarin.forms
有誰知道我如何綁定到標有的值???
有關更多解釋,這是我正在嘗試做的事情:
我希望能夠設置輸入框框架的寬度。 在此示例中,它們的寬度都相同。
你不能那樣做。 正如您所說, GridLength是一個結構,但可能比這更重要的是您設置的Value只是一個帶有 getter 的公共屬性(它甚至不是BindableProperty )。 這意味着您只能通過一種方法來設置它,在本例中恰好是GridLength
構造函數本身。 您可以在此處查看 GridLength 的代碼。
您可以做的是兩件事之一 - 保留您需要的所有寬度Auto
,或者將Grid
class 子類化。
如果您決定使用第一種方法 go,則無需編寫任何額外的代碼。 根據行和列文檔:
Auto
– 行高或列寬根據單元格內容自動調整(XAML 中的 Auto)。
乍一看,這應該可以完成工作,因為所有寬度都將采用子寬度的最大值(在本例中為 150)。 不幸的是,這給Grid
的渲染增加了一些開銷,而且在任何情況下都不小。 如果你在文檔中看得有點低,你會看到一個紅色警告,你應該:
盡量確保將盡可能少的行和列設置為
Auto
大小。 每個自動調整大小的行或列都會導致布局引擎執行額外的布局計算。 相反,如果可能,請使用固定大小的行和列。 或者,使用 GridUnitType.Star 枚舉值設置行和列以占用一定比例的空間。
這也可以在優化布局性能中再次看到,如果您還沒有閱讀,我強烈建議您閱讀。
也就是說,您可以使用第二種方法 go。 它背后的想法是在你的新 class 中有一個可綁定的屬性,並且在設置這個屬性時,你將更新你的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 將自動更改第三列。
當然,這不是最優雅的解決方案,因為它總是只更新第三列,但您可以從這里繼續。 由於我不確切知道情況是什么以及它會被用來做什么,我不能說什么是最好的選擇 - 要么為每一列創建更多屬性,要么創建一個包含鍵值的列表(甚至可能是一個單獨的類)綁定到它們 - 這樣你就可以為每一列動態設置它。
PS 而且,如果您從一開始就知道寬度,或者您只有 1 列需要Auto
,則 go 使用傳統方法。 盡量不要讓一切都過於復雜,並相應地設置列定義。
編輯:根據更新的問題,我們應該采取另一種方法。 從圖像中我無法完全理解整體模板是什么,但我們在這里有 2 個選項:
然而,無論我們選擇什么,該列對於所有視圖都將具有相同的寬度。 在這種情況下,我可以建議的是讓所有輸入的寬度也相同(將它們的HorizontalOptions
ntalOptions 設置為StartAndExpand
或FillAndExpand
)。 而不是明確設置它們的寬度,您可以嘗試將列的寬度設置為(取決於其他列的配置):
Star
(*) 或者您不希望該列與其他星號成比例 - 將其寬度設置為Star
。 這樣,該列將占用剩余的所有內容。Absolute
。您不應該嘗試動態更改列 - 這不會是一個好的用戶體驗,您還必須添加檢查何時停止。
總而言之,要么將第三列(包含條目)設置為Star
,要么設置為Absolute
。 如果您的其他列之一設置為Auto
而另一列具有Absolute
寬度,您可以輕松地將第三列設置為Star
,它將占用與剩余寬度相同的寬度)。 如果您想每次都使用“那么多”的寬度,則應使用Absolute
(將其與您希望可見的最大條目/符號一起使用)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.