【问题标题】:Setting Textblock/Button Visibility on WP8 App using MVVM使用 MVVM 在 WP8 应用程序上设置文本块/按钮可见性
【发布时间】:2015-03-30 03:14:52
【问题描述】:

我是 MVVM 的新手,我正在开发一个 WP8 应用程序,我希望能够根据点击其中一个按钮的时间来设置按钮和文本块的可见性。这是我的观点,试图更好地解释我的问题; (http://i.imgur.com/JvrxBkh.png - 无法在此声誉上发布图片)。

当用户点击“要睡觉”按钮时,我希望计数器文本块和“我醒了”按钮可见,而“要睡觉”按钮折叠起来。一旦按下“我醒了”按钮等,它就会以另一种方式工作。如果我没有使用 MVVM,我只需在按钮事件中设置 Visibility 值,但我被困在如何在使用 MVVM 模式时执行此操作。

我环顾四周,发现了一个使用转换器的解决方案,例如使用 BooleanToVisibilityConverter 类和 bool 属性,然后通过绑定到 ViewModel 中的 bool 值并将转换器值设置为StaticResource BooleanToVisibilityConverter。但它只是不适合我想要的方式。然后我的计数器文本块已经从 ViewModel 绑定了,所以我需要为这个文本块进行某种多重绑定吗?

希望我已经解释清楚了。看起来这应该是一个简单的任务,也许我只是想多了。

用一些代码sn-ps编辑

我所指的 View 组件;

<BooleanToVisibilityConverter x:Key="boolToVis" />

<TextBlock 
Grid.Row="2"
Text="{Binding Counter}"
FontSize="50"
TextWrapping="Wrap"
Foreground="White"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Visibility="{Binding VisibilityControl, Converter={StaticResource boolToVis}}"/>

<Button 
Grid.Row="3"
Width="230"
Height="70"
Content="I'm awake"
BorderThickness="0"
Background="Gray"
Margin="0,20,0,0"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Command="{Binding AwakeButtonCommand}"
Visibility="{Binding VisibilityControl, Converter={StaticResource boolToVis}}""/>

<Button 
Grid.Row="3"
Width="230"
Height="70"
Content="Going to sleep"
BorderThickness="0"
Background="Gray"
Margin="0,20,0,0"
HorizontalAlignment="Center"
VerticalAlignment="Center" 
Command="{Binding SleepButtonCommand}"
Visibility="{Binding VisibilityControl, Converter={StaticResource boolToVis}}"/>

那么在ViewModel中VisibilityControl就是;

private bool _visibilityControl;
public bool VisibilityControl
{
    if (_visibilityControl != value)
        _visibilityControl = value;

    OnPropertyChanged("VisibilityControl");
}

我有两个按钮,例如(我只会发布一个);

public ICommand AwakeButtonCommand
{
    get
    {
        return _awakeButtonCommand
            ?? (_awakeButtonCommand = new Resources.ActionCommand(() =>
        {
              VisibilityControl = true;
        }));
    }
}

显然,它不起作用。我认为让我失望的是因为我想在按下一个按钮时改变几件事,等等。这让我失望。

【问题讨论】:

  • 你能发布一些你已经尝试过的代码吗?布尔属性结合BooleanToVisibilityConverter 绝对是 MVVM 做这种事情的方式。您基本上使用布尔属性状态来显示和隐藏 UI 的元素。
  • 我已经发布了答案,但查看您的代码仍然很有用。
  • 是的,抱歉,没想到它对任何人都有用。我现在已经编辑了。

标签: c# windows-phone-8 mvvm visibility ivalueconverter


【解决方案1】:

我没有做过任何 Windows Phone 开发,但这是在 WPF 中进行的一种方法,它可能也适用于 WP。

首先,您的 ViewModel 将具有几个布尔属性,指示哪个状态处于活动状态(一个是另一个的镜像):

public bool IsAwake
{
    get
    {
        return _isAwake;
    }
    set
    {
        if (_isAwake != value)
        {
            _isAwake = value;
            // raise PropertyChanged event for *both* IsAwake and IsAsleep
        }
    }
}
bool _isAwake;

public bool IsAsleep
{
    get
    {
        return !_isAwake;
    }
}

然后您的 View 将包含 UI 的两个部分(睡眠和清醒),但会通过将它们的 Visibility 属性绑定到您的 ViewModel 的这些布尔属性来在两个部分之间切换:

<StackPanel>
    <StackPanel x:Name="AwakePart"
        Visibility="{Binding IsAwake, Converter={StaticResource btvc}}">
        ... "Going to sleep" button here ...
    </StackPanel>
    <StackPanel x:Name="AsleepPart"
        Visibility="{Binding IsAsleep, Converter={StaticResource btvc}}">
        ... Elapsed time text block and "I'm awake" button here ...
    </StackPanel>
</StackPanel>

您还需要在 XAML 资源中的某处有一个 BooleanToVisibilityConverter 实例:

<... .Resources>
    <BooleanToVisibilityConverter x:Key="btvc" />
</... .Resources>

我在此示例中使用了两个布尔属性,因为它使 XAML 更容易一些,但是您也可以使用 DataTrigger——假设它们在 Windows Phone 中具有这些属性——在这种情况下,您只需要一个布尔属性。然后,您将编写一个触发器来切换两个部分的Visibility 属性:

<DataTrigger Binding="{Binding IsAwake}" Value="True">
    <Setter TargetName="AwakePart" Property="Visibility" Value="Visible" />
    <Setter TargetName="AsleepPart" Property="Visibility" Value="Hidden" />
</DataTrigger>

为此,您需要首先在 XAML 中将“AwakePart”可见性显式设置为 Hidden,并确保在您的 ViewModel 中 IsAwake 属性默认为 false。您还需要删除可见性属性上的绑定(因为这些现在将通过触发器设置)。

【讨论】:

  • 所以我的方向是正确的,但我只需要更改两个状态的布尔值?
  • 我想你快到了。问题是您将所有三个控件的可见性绑定到同一个布尔值,我猜这意味着您要么同时看到所有三个控件,要么一个都看不到。根据答案尝试使用两个单独的布尔值的方法,看看是否有效。此外,尝试将您的控件放入容器中(我使用了StackPanel,但您可以使用任何容器)并在 containers 上而不是在单独的三个控件上设置可见性。
  • 通过使用两个单独的布尔值使其工作。感谢您的帮助史蒂文。
猜你喜欢
  • 1970-01-01
  • 2011-09-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-06-12
  • 2020-08-25
相关资源
最近更新 更多