在 INotifyPropertyChanged 上调用 IValueConverter 仅在开始时有效

轰炸机

我正在尝试根据枚举的值更改我的 PDF 中的哪个网格可见。枚举本身的值是基于菜单,并在选择菜单选项时,调用枚举值更改并调用propertyChangedEventHandler。

包含 PropertyChangedEventHandler 的类的代码如下:

public class ScreenToShow : INotifyPropertyChanged
{
    public enum MenuState { MenuPage, MenuChoice1, MenuChoice2, MenuChoice3};

    MenuState state;

    public MenuState _State
    {
        get { return state; }
        set
        {
            state = value;
            this.NotifyPropertyChanged("_State");
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    public void NotifyPropertyChanged(string propName)
    {
        this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propName));
    }
}

为了更改我的 WPF 窗口的内容,我将 4 个网格的可见性(每个网格的一个选项 + 起始页)绑定到此转换器,如下所示: 资源:

<Window.Resources>
    <local:ScreenToShow x:Key="myScreenToShow"></local:ScreenToShow>
    <local:VisibilityScreenConverter x:Key="myVisibilityScreenConverter"></local:VisibilityScreenConverter>
</Window.Resources>

四个网格之一的 XAML 代码:

<Grid DataContext="{Binding Source={StaticResource myScreenToShow}}" Name="MenuPage" Grid.Row="1" Visibility="{Binding Path= _State, Converter={StaticResource myVisibilityScreenConverter}, ConverterParameter='menuPage', UpdateSourceTrigger=Default, Mode=TwoWay}">

转换器的代码如下:

  class VisibilityScreenConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (value is ScreenToShow.State)
            {
                if((string)parameter == "menuPage")
                {
                    switch(value)
                    {
                        case ScreenToShow.State.MenuPage:
                            return Visibility.Visible;
                        default:
                            return Visibility.Hidden;
                    }
                }
                else if ((string)parameter == "menuChoice1")
                {
                    switch (value)
                    {
                        case ScreenToShow.State.MenuChoice1:
                            return Visibility.Visible;
                        default:
                            return Visibility.Hidden;
                    }
                }
                else if ((string)parameter == "menuChoice2")
                {
                    switch (value)
                    {
                        case ScreenToShow.State.MenuChoice2:
                            return Visibility.Visible;
                        default:
                            return Visibility.Hidden;
                    }
                }
                else // Menu choice 3
                {
                    switch (value)
                    {
                        case ScreenToShow.State.MenuChoice3:
                            return Visibility.Visible;
                        default:
                            return Visibility.Hidden;
                    }
                }
            }
            else
            {
                return Visibility.Visible;
            }
        }

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

在 MainWindow.cs 中,使用了以下代码:

    ScreenToShow screenToShowEnum = new ScreenToShow();

    public MainWindow()
    {
        DataContext = this;
        InitializeComponent();
        screenToShowEnum._State =  ScreenToShow.State.MenuPage;
    }

    private void MenuChoice1_Click(object sender, RoutedEventArgs e)
    {
        screenToShowEnum._State = ScreenToShow.State.MenuChoice1;
    }

    private void MenuChoice2_Click(object sender, RoutedEventArgs e)
    {
        screenToShowEnum._State = ScreenToShow.State.MenuChoice2;
    }

private void MenuChoice3_Click(object sender, RoutedEventArgs e)
        {
            screenToShowEnum._State = ScreenToShow.State.MenuChoice3;
        }

在启动时,代码工作正常,并且 NotifyPropertyChanged 和 Converter 都被调用(用 console.writeline 检查它)。此外,不同网格的可见性按预期处理。选择其中一个菜单选项时,也会按预期调用propertyChangEdHandler。但是,不同网格的可见性不会改变。我做错了什么,在启动时根据我的代码更改可见性,但在稍后阶段更改我的枚举值时却没有?

谢谢!

迪彭沙

问题是您指的是两个完全不同的ViewModel对象,一个由您的 xaml 视图使用,另一个由文件背后的代码使用。

DataContext在代码隐藏文件中设置属性或在 xaml 文件中设置它起诉:

<Window.DataContext>
    <StaticResource ResourceKey="myScreenToShow" />
</Window.DataContext>

如果您使用第二种方法,请确保强制转换并使用您的DataContextin 事件处理程序:

private void MenuChoice1_Click(object sender, RoutedEventArgs e)
{
    (DataContext as ScreenToShow)._State = ScreenToShow.MenuState.MenuChoice1;
}

private void MenuChoice2_Click(object sender, RoutedEventArgs e)
{
    (DataContext as ScreenToShow)._State = ScreenToShow.MenuState.MenuChoice2;
}

private void MenuChoice3_Click(object sender, RoutedEventArgs e)
{
    (DataContext as ScreenToShow)._State = ScreenToShow.MenuState.MenuChoice3;
}

演示代码:

<Window
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfApplicationTest"
        xmlns:Themes="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Aero2" x:Class="WpfApplicationTest.MainWindow"
        mc:Ignorable="d"
        x:Name="win"
        WindowStartupLocation="CenterOwner"
        Title="MainWindow" Height="300" Width="300">
    <Window.Resources>
        <ResourceDictionary>
            <local:ScreenToShow x:Key="myScreenToShow"></local:ScreenToShow>
            <local:VisibilityScreenConverter x:Key="myVisibilityScreenConverter"></local:VisibilityScreenConverter>
        </ResourceDictionary>
    </Window.Resources>
    <Window.DataContext>
        <StaticResource ResourceKey="myScreenToShow" />
    </Window.DataContext>
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition />
            <RowDefinition />
        </Grid.RowDefinitions>
        <StackPanel Orientation="Horizontal">
            <Button Margin="5" Content="Menu 1" Click="MenuChoice1_Click" />
            <Button Margin="5" Content="Menu 2" Click="MenuChoice2_Click" />
            <Button Margin="5" Content="Menu 3" Click="MenuChoice3_Click" />
        </StackPanel>

        <Grid DataContext="{Binding Source={StaticResource myScreenToShow}}"
              Name="MenuPage1"
              Grid.Row="1"
              Visibility="{Binding Path= _State, Converter={StaticResource myVisibilityScreenConverter}, ConverterParameter='menuChoice1', UpdateSourceTrigger=Default, Mode=TwoWay}">
            <TextBlock Text="Menu 1" FontSize="24" />
        </Grid>
        <Grid DataContext="{Binding Source={StaticResource myScreenToShow}}"
              Name="MenuPage2"
              Grid.Row="1"
              Visibility="{Binding Path= _State, Converter={StaticResource myVisibilityScreenConverter}, ConverterParameter='menuChoice2', UpdateSourceTrigger=Default, Mode=TwoWay}">
            <TextBlock Text="Menu 2" FontSize="24" />
        </Grid>
        <Grid DataContext="{Binding Source={StaticResource myScreenToShow}}"
              Name="MenuPage3"
              Grid.Row="1"
              Visibility="{Binding Path= _State, Converter={StaticResource myVisibilityScreenConverter}, ConverterParameter='menuChoice3', UpdateSourceTrigger=Default, Mode=TwoWay}">
            <TextBlock Text="Menu 3" FontSize="24" />
        </Grid>
    </Grid>
</Window>

文件隐藏代码:

class VisibilityScreenConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value is ScreenToShow.MenuState)
        {
            var state = (ScreenToShow.MenuState)value;
            if ((string)parameter == "menuPage")
            {
                switch (state)
                {
                    case ScreenToShow.MenuState.MenuPage:
                        return Visibility.Visible;
                    default:
                        return Visibility.Hidden;
                }
            }
            else if ((string)parameter == "menuChoice1")
            {
                switch (state)
                {
                    case ScreenToShow.MenuState.MenuChoice1:
                        return Visibility.Visible;
                    default:
                        return Visibility.Hidden;
                }
            }
            else if ((string)parameter == "menuChoice2")
            {
                switch (state)
                {
                    case ScreenToShow.MenuState.MenuChoice2:
                        return Visibility.Visible;
                    default:
                        return Visibility.Hidden;
                }
            }
            else // Menu choice 3
            {
                switch (state)
                {
                    case ScreenToShow.MenuState.MenuChoice3:
                        return Visibility.Visible;
                    default:
                        return Visibility.Hidden;
                }
            }
        }
        else
        {
            return Visibility.Visible;
        }
    }

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

public class ScreenToShow : INotifyPropertyChanged
{
    public enum MenuState { MenuPage, MenuChoice1, MenuChoice2, MenuChoice3 };

    MenuState state;

    public MenuState _State
    {
        get { return state; }
        set
        {
            state = value;
            this.NotifyPropertyChanged("_State");
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    public void NotifyPropertyChanged(string propName)
    {
        this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propName));
    }
}

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
    }

    private void MenuChoice1_Click(object sender, RoutedEventArgs e)
    {
        (DataContext as ScreenToShow)._State = ScreenToShow.MenuState.MenuChoice1;
    }

    private void MenuChoice2_Click(object sender, RoutedEventArgs e)
    {
        (DataContext as ScreenToShow)._State = ScreenToShow.MenuState.MenuChoice2;
    }

    private void MenuChoice3_Click(object sender, RoutedEventArgs e)
    {
        (DataContext as ScreenToShow)._State = ScreenToShow.MenuState.MenuChoice3;
    }
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

在 INotifyPropertyChanged 上调用 IValueConverter 仅在开始时有效

来自分类Dev

WPF:IValueConverter没有被调用

来自分类Dev

图像RotateFlip仅在直接调用时有效

来自分类Dev

jQuery Ajax调用仅在首页加载时有效

来自分类Dev

图像RotateFlip仅在直接调用时有效

来自分类Dev

仅在DataGrid上滚动时才调用IValueConverter

来自分类Dev

具有MarkupExtension的IValueConverter

来自分类Dev

JavaScript在使用Node调用时有效,但仅在从HTML调用时才有效

来自分类Dev

使用Ajax调用追加div仅在首次加载时有效

来自分类Dev

播放模板仅在带括号调用时有效

来自分类Dev

从视图观察控制器属性仅在从didInsertElement调用get('controller')时有效

来自分类Dev

Spring @Transactional仅在调用方也是@Transactional时有效

来自分类Dev

Spring @Transactional仅在调用方也是@Transactional时有效

来自分类Dev

PHP函数中的javaScript代码仅在首次调用时有效

来自分类Dev

QLocale setDefault 仅在第二次调用时有效

来自分类Dev

BluetoothGattCallback仅在onConnectionStateChange上调用

来自分类Dev

INotifyPropertyChanged带有枚举

来自分类Dev

带有列表的 INotifyPropertyChanged

来自分类Dev

Sails.js / Waterline .add()和.remove()仅在第二次调用时有效

来自分类Dev

使用jquery序列化上传多个文件仅在第二次调用时有效

来自分类Dev

使用openCV从网络摄像头捕获图像的功能仅在首次调用时有效

来自分类Dev

xaml没有看到我的ivalueconverter

来自分类Dev

存根所有在类上调用的方法

来自分类Dev

在ArrayList的所有组合上调用方法的最有效方法?

来自分类Dev

在变量上调用方法时为nil,但仅在变量上调用时为nil

来自分类Dev

为什么不为DataGrid自动生成的列调用IValueConverter

来自分类Dev

为什么在User :: first()上调用方法有效,但User :: where(...)无效?

来自分类Dev

在2D坐标ndarray上调用函数的最有效方法是什么?

来自分类Dev

在对象上调用有效方法后如何收集错误?

Related 相关文章

  1. 1

    在 INotifyPropertyChanged 上调用 IValueConverter 仅在开始时有效

  2. 2

    WPF:IValueConverter没有被调用

  3. 3

    图像RotateFlip仅在直接调用时有效

  4. 4

    jQuery Ajax调用仅在首页加载时有效

  5. 5

    图像RotateFlip仅在直接调用时有效

  6. 6

    仅在DataGrid上滚动时才调用IValueConverter

  7. 7

    具有MarkupExtension的IValueConverter

  8. 8

    JavaScript在使用Node调用时有效,但仅在从HTML调用时才有效

  9. 9

    使用Ajax调用追加div仅在首次加载时有效

  10. 10

    播放模板仅在带括号调用时有效

  11. 11

    从视图观察控制器属性仅在从didInsertElement调用get('controller')时有效

  12. 12

    Spring @Transactional仅在调用方也是@Transactional时有效

  13. 13

    Spring @Transactional仅在调用方也是@Transactional时有效

  14. 14

    PHP函数中的javaScript代码仅在首次调用时有效

  15. 15

    QLocale setDefault 仅在第二次调用时有效

  16. 16

    BluetoothGattCallback仅在onConnectionStateChange上调用

  17. 17

    INotifyPropertyChanged带有枚举

  18. 18

    带有列表的 INotifyPropertyChanged

  19. 19

    Sails.js / Waterline .add()和.remove()仅在第二次调用时有效

  20. 20

    使用jquery序列化上传多个文件仅在第二次调用时有效

  21. 21

    使用openCV从网络摄像头捕获图像的功能仅在首次调用时有效

  22. 22

    xaml没有看到我的ivalueconverter

  23. 23

    存根所有在类上调用的方法

  24. 24

    在ArrayList的所有组合上调用方法的最有效方法?

  25. 25

    在变量上调用方法时为nil,但仅在变量上调用时为nil

  26. 26

    为什么不为DataGrid自动生成的列调用IValueConverter

  27. 27

    为什么在User :: first()上调用方法有效,但User :: where(...)无效?

  28. 28

    在2D坐标ndarray上调用函数的最有效方法是什么?

  29. 29

    在对象上调用有效方法后如何收集错误?

热门标签

归档