【问题标题】:WP7: change the background of a border with converterWP7:使用转换器更改边框的背景
【发布时间】:2013-10-15 02:43:13
【问题描述】:

我对转换器很着迷。我知道我必须在需要时使用它来更改我的值的“退出值”,但我不知道如何正确使用我的情况。

我有我的简单 MVVM(仅限 3 个字段)和带有我的项目列表的主窗口。第一项根据函数计算,可以显示YES或NOT,其他值直接绑定。

这很好用,但我需要根据我在第一个计算字段中的 YES 或 NOT 值更改背景和前景色。例如:

YES (must be blue) - ITEM 1
NO (must be grey)  - ITEM 2
YES (must be blue) - ITEM 3

虽然我的数据库中的内部值是(在这种情况下,计算是模数):

2 - ITEM 1
3 - ITEM 2
4 - ITEM 3

我的 ListBox 代码是这样的:

<phone:PhoneApplicationPage 
x:Class="Pasti.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignWidth="480" d:DesignHeight="768"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}"
SupportedOrientations="Portrait" Orientation="Portrait"
shell:SystemTray.IsVisible="True">

<Grid x:Name="LayoutRoot" Background="Transparent">
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto"/>
        <RowDefinition Height="*"/>
    </Grid.RowDefinitions>

    <StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28">
        <TextBlock Text="My App" Style="{StaticResource PhoneTextNormalStyle}" />
        <TextBlock Text="My List" Style="{StaticResource PhoneTextTitle1Style}" />
    </StackPanel>

<ListBox x:Name="lstPills" Grid.Row="1" ItemsSource="{Binding AllItems}">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <Grid HorizontalAlignment="Stretch" Width="440">
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="90" />
                    <ColumnDefinition Width="*" />
                </Grid.ColumnDefinitions>
                <Border Background="HERE MUST GO THE CONVERTER, I SUPOSE">
                    <TextBlock Text="{Binding IsPair, Mode=TwoWay}"/>
                </Border>
                <TextBlock
                    Text="{Binding Name}"
                    FontSize="{StaticResource PhoneFontSizeLarge}"
                    Grid.Column="1"
                    VerticalAlignment="Center"/>
            </Grid>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>
</Grid>
</phone:PhoneApplicationPage>

此页面的 CS 代码如下:

public partial class MainPage : PhoneApplicationPage
{
    // Constructor
    public MainPage()
    {
        InitializeComponent();

        // Set the page DataContext property to the ViewModel.
        this.DataContext = App.ViewModel;
    }
}

对于计算字段,我将其添加到模型中(_myNumber 包含我必须检查的值):

    // Define a custom field based on some database values
    // Get is calculated, while set will force it to refresh by Notifying
    public string IsPair
    {
        get
        {
            return _myNumber % 2 == 0 ? "YES" : "NO";
        }
        set
        {
            NotifyPropertyChanged("IsPair");
        }
    }

注意:因为我不知道强制刷新列表的其他方法,所以我将 set 属性设置为仅通知和双向模式,当我希望它重新计算时,我只执行 IsPair = ""。如果有其他方法可以做到这一点,将受到欢迎。

那么,有了这些信息,我如何制作一个转换器,根据我的 IsPair 值,将边框的 Background 属性设置为蓝色或灰色?我看到了很多 Converter 示例,但仍然不明白如何做到这一点。

我想我必须在 MainPage.cs 中的 MainPage 类下放置这样的内容:

// Converter for the YES-NO column on the list
public class IsPairConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (MY_CALCULATED_VALUE == "YES")
            return "Blue";

        return "Grey";
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

但是如何获取MY_CALCULATED_VALUE,以及如何在Border的Background值中设置转换器呢?

【问题讨论】:

    标签: c# windows-phone-7 mvvm converter


    【解决方案1】:

    如此接近!

    首先,将背景绑定到IsPair并使用转换器:

    <Border Background="{Binding IsPair, Converter={StaticResource IsPairConverter}}">
        <TextBlock Text="{Binding IsPair, Mode=TwoWay}"/>
    </Border>
    

    在你的转换器中,根据值创建一个画笔:

    public class IsPairConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            // You might want to add additional checks for type safety
            var calculatedValue = (string)value; 
    
            var color = calculatedValue == "YES" ? Colors.Blue : Colors.Gray;
    
            return new SolidColorBrush { Color = color };
        }
    
        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
    

    你已经完成了。


    如果您希望只计算一次值,而不是每次调用IsPair,您可以在MyNumber 的setter 中进行计算并将其分配给IsPair

    private int myNumber;
    
    public string IsPair { get; protected set; }
    
    protected int MyNumber
    {
        get
        {
            return this.myNumber;
        }
    
        set
        {
            this.myNumber = value;
            this.IsPair = value % 2 == 0 ? "YES" : "NO";
            this.NotifyPropertyChanged("IsPair");
        }
    }
    

    【讨论】:

    • 太棒了!以及如何在 XAML 中声明 de 转换器?非常感谢
    • 在页面的资源中声明:&lt;local:IsPairConverter x:Key="IsPairConverter"/&gt;
    • 好的,我还必须为本地添加命名空间:xmlns:local="clr-namespace:MyApp",然后我可以添加资源&lt;phone:PhoneApplicationPage.Resources&gt; &lt;local:IsPairConverter x:Key="IsPairConverter"/&gt; &lt;/phone:PhoneApplicationPage.Resources&gt;。非常感谢。成功了!!!
    • 最后一个问题。每次我读取时都会调用 IsPair 属性绑定,所以如果我在转换器中使用它,所有的计算都会一次又一次地为同一个项目完成(我已经测试过了)。在我的示例中,将为 Text、ForeGround 和 BackGround 调用(绑定)isPair,因此计算将完成 3 次。我可以避免重新计算相同的值 3 次吗?因为每次“Binding IsPair”都会做get,每次都会计算。
    • @Eagle 然后将IsPair声明为普通属性,创建MyNumber属性(而不仅仅是一个字段),并在MyNumber属性的setter中进行计算
    猜你喜欢
    • 1970-01-01
    • 2019-11-28
    • 2014-04-29
    • 2011-03-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多