caliburn.micro绑定元素对viewmodel函数的可见性,而不是属性

时间:2015-06-08 16:42:38

标签: c# wpf xaml binding caliburn.micro

首先 - 我很抱歉,如果它是重复的 - 一直在寻找一段时间而无法找到答案,

我们正在使用caliburn.micro,因此解决方案必须使用此工具。

我们有一个由9个按钮组成的视图 - 然而 - 并非所有按钮都可以在同一时间显示,它取决于系统上的事件。 每个按钮的可见性根据当前状态显示为可见或折叠,但由于它是大量按钮,并且将来可能会增加,我宁愿只有一个功能来执行此操作(接收名称或枚举并返回可见性)而不是将大量属性绑定到每个按钮。

它甚至是一种选择吗?我似乎找不到以任何传统方式做到这一点的方法。

由于事件是从软件外部接收的,我们在视图级别上进行此操作并不是真正的选择(或者至少 - 不是正确的)

编辑:这是我要修改的视图片段:

            <Grid Margin="0">
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="120" />
                    <ColumnDefinition Width="Auto" />
                </Grid.ColumnDefinitions>

                <uiviews:PhonePadView Grid.Column="0" x:Name="DestinationDn" cal:Bind.Model="UI.ViewModels.PhonePadViewModel" />

                <Button  Grid.Column="1" Content="Dial" Style="{StaticResource PhonePadBasicFunctionsButtons}" x:Name="MakeCall" Visibility="{Binding btnMakeCallVisibility}" />
                <Button  Grid.Column="1" Content="Answer" Style="{StaticResource PhonePadBasicFunctionsButtons}" x:Name="AnswerCall" Visibility="{Binding btnAnswerCallVisibility}" />
                <Button  Grid.Column="1" Content="Hang-up" Style="{StaticResource PhonePadBasicFunctionsButtons}" x:Name="ReleaseCall" Visibility="{Binding btnReleaseCallVisibility}" />
                <Button  Grid.Column="1" Content="Hold" Style="{StaticResource PhonePadBasicFunctionsButtons}" x:Name="HoldCall" Visibility="{Binding btnHoldCallVisibility}" />

            </Grid>

正如你所看到的,我需要为每个按钮设置不同的属性,我拒绝相信这是唯一的方法,我确实有一个属性保持当前状态(电话正在响铃,在通话中,拨号等)并且很容易在VM上有一个功能,告诉哪个按钮应该是可见的,哪个按钮不应该是,并且在它上面我们当前有9个按钮,但它可以很容易地扩展更多,所以我在这里寻找最模块化的代码

2 个答案:

答案 0 :(得分:8)

开箱即用,如果你用&#34; IsVisible&#34;来命名。后缀,Caliburn Micro将切换可见性。

在视图上:

<Grid Name="ConfigEditorIsVisible">
    <TextBlock>Test</TextBlock>
</Grid>

在ViewModel上:

public bool ConfigEditorIsVisible { get; set; }

答案 1 :(得分:0)

所以......最后这就是我所做的: 在VM上:

    private HashSet<string> actionsEnabledSet = null;
    public HashSet<string> ActionsEnabledSet
    {
        get { return actionsEnabledSet; }
        set
        {
            actionsEnabledSet = value;
            NotifyOfPropertyChange(() => ActionsEnabledSet);
        }
    }

根据我希望可见的项目更改哈希集。

具有转换功能的(多)转换器:

    public object Convert(object[] value, Type targetType, object parameter,
            System.Globalization.CultureInfo culture)
    {
        if (value[0].GetType() == typeof(HashSet<string>))
        {
            if (value[1].GetType() == typeof(string))
            {
                if (((HashSet<string>)value[0]).Contains((string)value[1]))
                    return Visibility.Visible;
            }
        }
        return Visibility.Collapsed;
    }

查看按钮样式:(尽可能避免重复代码)

    <Style TargetType="Button" x:Key="PhonePadBasicFunctionsButtons" >
        <Setter Property="Margin" Value="0,0,0,0" />
        <Setter Property="Focusable" Value="False" />
        <Setter Property="HorizontalAlignment" Value="Stretch" />
        <Setter Property="Width" Value="75" />
        <Setter Property="Visibility">
            <Setter.Value>
                <MultiBinding Converter="{StaticResource PhoneActionVisibilityConverter1}">
                    <Binding Path="ActionsEnabledSet" Mode="OneWay"/>
                    <Binding RelativeSource="{RelativeSource Self}" Path="Tag" />
                </MultiBinding>
            </Setter.Value>
        </Setter>
    </Style>

按钮的堆叠面板看起来像这样:

                <Button  Content="Call" Style="{StaticResource PhonePadBasicFunctionsButtons}" x:Name="MakeCall" Tag="MakeCall" cal:Message.Attach="MakeCall" />
                <Button  Content="Answer" Style="{StaticResource PhonePadBasicFunctionsButtons}" x:Name="AnswerCall" Tag="AnswerCall" cal:Message.Attach="AnswerCall" />

真的很恼火,我无法找到一种方法来绑定&#34;标记&#34; to&#34; x:name&#34;,但添加新按钮就像添加一行一样简单,以这种方式获得代码感觉更好, 我希望对如何做到这一点有任何想法,我觉得它很优雅,但我觉得它可以更容易阅读/实施。

我不得不使用multibinding,因为使用covnerterproperty不是一个选项 - 你不能将一个元素绑定到一个属性,看起来希望这对未来的某个人有所帮助 - 这是一个很好的挑战:)

感谢所有试图提供帮助的人 - 你让我从我的盒子里拿出来并实际寻找答案!