简体   繁体   English

使用MVVM在WP8 App上设置文本块/按钮可见性

[英]Setting Textblock/Button Visibility on WP8 App using MVVM

I'm new to MVVM and I'm working on a WP8 app and I'd like to be able to set the visibility of buttons and a textblock based on when one of those buttons were tapped. 我是MVVM的新手,并且正在WP8应用程序上工作,我希望能够根据敲击这些按钮之一的时间来设置按钮和文本块的可见性。 Here's my View to try and explain my problem a bit better; 这是我的观点,试图更好地解释我的问题; ( http://i.imgur.com/JvrxBkh.png - can't post an image on this reputation) . http://i.imgur.com/JvrxBkh.png-无法在此声誉上发布图像)。

When the user taps the "Going to sleep" button, I'd like the counter textblock and the "I'm awake" button to be visible with the "Going to sleep" button to be collapsed. 当用户点击“进入睡眠”按钮时,我希望计数器文本块和“我醒来”按钮可见,而“进入睡眠”按钮可以折叠。 It'll then work the other way once the "I'm awake" button is pressed, etc. If I wasn't using MVVM I'd just set the Visibility value inside the button event, but I'm stuck on how to do this when using the MVVM pattern. 然后,一旦按下“我醒了”按钮,它将以另一种方式起作用。依此类推。如果我不使用MVVM,则只需在按钮事件中设置“可见性”值,但是我仍然坚持使用MVVM模式时,请执行此操作。

I've looked around and come across a solution using a converter such as using a BooleanToVisibilityConverter class and a bool property and then setting the visibility by binding to the bool value from the ViewModel and setting the converter value for the visibility to the StaticResource BooleanToVisibilityConverter. 我四处查看并遇到了使用转换器的解决方案,例如使用BooleanToVisibilityConverter类和bool属性,然后通过绑定到ViewModel的bool值设置可见性,并将可见性的转换器值设置为StaticResource BooleanToVisibilityConverter。 But it just doesn't work for me the way I want. 但这对我不起作用。 Then my counter textblock has a bind already from the ViewModel so would I need some kind of multi-binding for this textblock? 然后我的计数器文本块已经具有ViewModel的绑定,因此我需要对该文本块进行某种形式的多重绑定吗?

Hopefully I've explained myself OK. 希望我已经向自己解释了。 It seems like it should be a simple task that maybe I'm just over thinking or something. 似乎这应该是一个简单的任务,也许我只是在想什么。

EDIT With some code snippets 使用一些代码片段进行编辑

The View components that I was referring to; 我指的是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}}"/>

Then in the ViewModel VisibilityControl is just; 然后在ViewModel中,VisibilityControl是公正的;

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

    OnPropertyChanged("VisibilityControl");
}

And I have the two buttons such as (I'll just post one up); 我有两个按钮,例如(我将张贴一个按钮);

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

It doesn't work, obviously. 显然,它不起作用。 I think what's throwing me is because I want several things changed when one button is pressed, etc. It's throwing me off. 我认为让我投掷的是因为我希望在按下一个按钮等操作时发生几处更改。这使我失望。

I've not done any Windows Phone development but here's one way of doing it in WPF that might be applicable to WP also. 我没有做任何Windows Phone开发,但这是在WPF中完成的一种方法,该方法也可能适用于WP。

First, your ViewModel would have a couple of Boolean properties indicating which state is active (one would be a mirror of the other): 首先,您的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;
    }
}

Then your View would contain both parts of the UI (asleep & awake) but would switch between the two parts by binding their Visibility property to these Boolean properties of your ViewModel: 然后,您的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>

You will also need a BooleanToVisibilityConverter instance somewhere in your XAML resources: 您还将在XAML资源中的某个地方需要一个BooleanToVisibilityConverter实例:

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

I've used two Boolean properties in this example as it makes the XAML a little easier, however you could also use a DataTrigger -- assuming they have those in Windows Phone -- in which case you would only need one Boolean property. 在此示例中,我使用了两个布尔属性,因为它使XAML变得更容易了,但是您也可以使用DataTrigger (假设它们在Windows Phone中具有),在这种情况下,您只需要一个布尔属性。 You would then write a trigger to toggle the Visibility properties of the two parts: 然后,您将编写触发器以切换两个部分的Visibility属性:

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

For this to work you would need to explicitly set the "AwakePart" visibility to Hidden in the XAML to start with and ensure that in your ViewModel the IsAwake property is false by default. 为此,您首先需要在XAML中将“ AwakePart”可见性显式设置为Hidden ,并确保在ViewModel中,默认情况下IsAwake属性为false。 You would also need to remove the bindings on the visibility properties (as these would now be set via the trigger). 您还需要删除可见性属性上的绑定(因为这些绑定现在将通过触发器进行设置)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM