c# - 导航期间多次调用 ValueConverter

标签 c# windows-phone-8 mvvm mvvm-light

在与 Binding 一起使用的 Converter 中,有些东西我无法理解。 :-(

我用 Mvvm-Light 创建了一个简单的例子......

这里是完整的解决方案:https://testbindingwithconverter.codeplex.com/SourceControl/latest

这里是一张图片:http://i.stack.imgur.com/wUf89.png

和摘要源代码下方:

CarsView

<Rectangle Grid.Row="0" 
               Opacity="{Binding SelectedCar, Converter={StaticResource IntToOpacityConverter}}" 
               Fill="#FFD1E22A"  />
    <ListBox Grid.Row="1" 
             ItemsSource="{Binding Cars}" 
             SelectedItem="{Binding SelectedCar, Mode=TwoWay}" >
        <ListBox.ItemTemplate>
            <DataTemplate>
                    <StackPanel>
                        <TextBlock Text="{Binding Company}" />
                        <TextBlock Text="{Binding Name}" />
                        <TextBlock Text="{Binding Year}" />
                    </StackPanel>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>

CarsViewModel

public class CarsViewModel : ViewModelBase
{
    private ObservableCollection<Car> cars;
    private Car selectedCar;

    public CarsViewModel()
    {
        if (IsInDesignMode)
        {
        }
        else
        {
            // INIT
            this.cars = new ObservableCollection<Car>();
            this.selectedCar = null;

            // FAKE DATA
            for (int i = 1; i <= 10; i++)
            {
                Car newCar = new Car { Id = i, Company = "Company_" + i, Name = "Name_" + i, Year = "200" + i };
                Cars.Add(newCar);
            }
        }
    }

    public ObservableCollection<Car> Cars
    {
        get 
        {
            return cars; 
        }

        set 
        {
            if (cars != value)
            {
                cars = value;
                RaisePropertyChanged(() => Cars);
            }
        }
    }

    public Car SelectedCar
    {
        get
        {
            return selectedCar;
        }

        set
        {
            if (value != selectedCar)
            {
                selectedCar = value;
                RaisePropertyChanged(() => SelectedCar);
            }
        }
    }
}

转换器

public class IntToOpacityConverter : System.Windows.Data.IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        double opacity = 1;
        Car c = value as Car;

        if (c != null)
        {
            if (c.Id == 5)
            {
                opacity = 0.3;
            }
        }

        System.Diagnostics.Debug.WriteLine("[IntToOpacityConverter] \t" + "Rectangle Opacity: " + opacity);
        return opacity;
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        // One-Way conversion!
        return null;
    }

在 CarsView 中,当我点击 ListBox 的第 5 项时,Rectangle 的属性 Opacity 设置为值 0.3,否则设置为值 1。

现在,当我返回到 HomeView 然后再次返回到 CarsView 时,如果我在项目之间点击转换器被调用 2 次! 再一次,如果我返回到 HomeView 并返回到 CarsView,转换器被调用 3 次!等等……

为什么?

最佳答案

嘿文森佐佩特罗尼奥,

我不会在每次导航时创建一个新的 CarsViewModel(),因为它不会将您的颜色保存在 Rectangle 上,相反,您希望在导航离开时取消绑定(bind) DataContent。

CarsView.xaml/CarsView.xaml.cs 上创建一个卸载事件:

<phone:PhoneApplicationPage  Unloaded="PhoneApplicationPage_Unloaded">
private void PhoneApplicationPage_Unloaded(object sender, RoutedEventArgs e)
{
    this.DataContext = null;
}

然后您需要检查 Car Set 函数是否为空值,这样它就不会将您的选择更改为空值。

public Car SelectedCar
{
    get
    {
        System.Diagnostics.Debug.WriteLine("[CARSVIEWMMODEL] \t" + "GET SelectedCar");
        return selectedCar;
    }

    set
    {
        if (value != selectedCar && value != null)
        {
            selectedCar = value;
            System.Diagnostics.Debug.WriteLine("[CARSVIEWMMODEL] \t" + "SET SelectedCar");
            RaisePropertyChanged(() => SelectedCar);
       }
    }
}


如果您应用更改,您会看到它会按照您想要的方式运行,而且当您导航回“汽车”页面时它会保存该矩形的颜色。

关于c# - 导航期间多次调用 ValueConverter,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25490577/

相关文章:

c# - 如何从自定义列表框中将按钮、TexBlocks 等添加到 Dynamic ObservableCollection Tabitem

c# - 此 Linq 查询的哪一部分对 nHibernate 无效?

c# - 使用 C# 在 ASP.Net 中使用 Google Drive API 将文件上传到 Google Drive

c# - 在代码中动态设置控件的 StaticResource 样式

ruby - 从 Ruby 连接到适用于 Windows Phone 8 的 Microsoft 推送通知服务

mvvm - 在 Windows 10 通用应用程序中将命令绑定(bind)到集线器部分标题单击

c# - 发送带有命令参数的对象

c# - 在子类的构造函数中调用基构造函数

android - 有没有办法从对服务器的http请求确定移动操作系统(iOS、Android等)?

wpf - 无法加载 FsXaml.Wpf.TypeProvider