如何使用mvvmcross fluentLayout修改约束

时间:2017-04-18 23:28:41

标签: xamarin xamarin.ios mvvmcross cirrious.fluentlayout

我比喻地把头发拉出来。我从这篇文章中读到了#34; http://gregshackles.com/fluentlayout-2-5/" FluentLayout现在支持约束编辑/删除,但它似乎并不适合我。我的方案是在单击按钮时切换UIView中文本字段的可见性。

我尝试了以下内容。

:一种。修改高度约束

 var height = isVisible ? textfield.Height().EqualTo(0) : textfield.WithSameHeight(textfieldContainer).Multiplier(1 / 3);
            textfieldContainer.Add(textfield);
            textfieldContainer.SubviewsDoNotTranslateAutoresizingMaskIntoConstraints();
            textfieldContainer.AddConstraints(
                    textfield.WithSameLeft(textfieldContainer).Plus(12),
                    textfield.WithSameTop(textfieldContainer).Plus(24),
                    textfield.WithSameWidth(textfieldContainer),
                    height
                );

B中。使用SetActive(false) - 在绝望中尝试了这个

 textfieldContainer.Add(textfield);
            textfieldContainer.SubviewsDoNotTranslateAutoresizingMaskIntoConstraints();
            textfieldContainer.AddConstraints(
                    textfield.WithSameLeft(textfieldContainer).Plus(12).SetActive(!isVisible),
                    textfield.WithSameTop(textfieldContainer).Plus(24).SetActive(!isVisible),
                    textfield.WithSameWidth(textfieldContainer).SetActive(!isVisible),
                    textfield.WithSameHeight(textfieldContainer).WithMultiplier(1 / 4).SetActive(!isVisible)
                );

预期结果

根据可见性

,文本字段应该可见

实际结果

文本字段的高度永远不会改变,因此它始终可见

1 个答案:

答案 0 :(得分:3)

我的猜测是您的 @model IEnumerable<Tree_List.Models.H_Table> @{ ViewBag.Title = "Index"; } @*<script src="~/Scripts/ListControlScript.js"></script>*@ <script src="~/Scripts/jquery-1.10.2.min.js"></script> <div> @helper PopulateDivs(IEnumerable<Tree_List.Models.H_Table> foos) { @foreach (var item in Model) { <div id="wrapper" class="something" data-id="@item.PARENT_ID" data-parent="@item.PARENT_ID"> //I don't know the real structure you are looking for but this will work with recursion @if(Model.Any(m=> m.Parent_ID == item.ID)) { @PopulateDivs(Model.Where(m=> m.Parent_ID == item.ID)) } <ul> <input type="button" class="toggler" onclick="ShowMsg()"> <li class="roots" > @item.NAME <input class="add_btn" type="button" value="Add" /> <input class="edit_btn" type="button" value="Edit" /> <input class="delete_btn" type="button" value="Delete" /> </li> </ul> </div> } } </div> <script> $(function () { }); </script> 变量在页面生命周期中设置了一次,并且在该点之后没有变化。实现您所需要的方法如下:

首先,将按钮单击绑定到更改heightboolean状态的命令,以便在按钮为ViewModel时更改boolean的值点:

bindingSet.Bind(yourButton).To(vm => vm.YourCommand);

MvxCommand _yourCommand;
public MvxCommand YourCommand
    => _yourCommand ?? _yourCommand = new MvxCommand(ReverseMyBool);

void ReverseMyBool()
{
    YourBoolean = !YourBoolean;
}

如果有必要,请在构建YourBoolean期间将ViewModel设置为true,具体取决于您是否希望在页面加载期间隐藏字段。既然ViewModel属性对于是否应该隐藏UITextField保持准确的真/假状态,请将UITextField本身绑定到Hidden到布尔值(您可能需要使用value converter来反转值 - 如果Hidden为真,则视图不可见):

bindingSet.Bind(textfield).For(c => c.Hidden).To(vm => vm.YourBoolean);

接下来,创建与两种情况相关的FluentLayout变量(您的视图可见并被隐藏),并应用它们:

var textFieldWithOneThirdContainerHeight = textfield.WithSameHeight(textFieldContainer).WithMultiplier(1f /3f);
var textFieldWithZeroHeight = textField.Height().EqualTo(0f);

textfieldContainer.AddConstraints(textFieldWithOneThirdContainerHeight, textFieldWithZeroHeight, /*other constraints here*/);

最后,将Active的约束绑定到boolean上的ViewModel - 请注意,需要使用转换器对其进行反转:

bindingSet.Bind(textFieldWithOneThirdContainerHeight).For(c => c.Active).To(vm => vm.YourBoolean).WithConversion(new ReverseBooleanValueConverter());
bindingSet.Bind(textFieldWithZeroHeight).For(c => c.Active).To(vm => vm.YourBoolean);

ReverseBooleanValueConverter看起来像这样:

public class ReverseBooleanValueConverter: MvxValueConverter<bool, bool>
{
    protected override bool Convert(bool value, Type targetType, object parameter, CultureInfo culture) 
        => !value;
}

YourBoolean为真时,您的UITextField应该是不可见的,其高度应为0f。当YourBoolean为假时,它应该是可见的,并且应该具有其容器高度的三分之一。