【问题标题】:BoolToVisibilityConverter not firing in UWPBoolToVisibilityConverter 未在 UWP 中触发
【发布时间】:2023-03-16 20:50:02
【问题描述】:

我完全被这个难住了。我在 UWP/C# 中有一个 UserControl,其中包含几个 Border 对象,这些对象是通往房间的门。我有 4 个 DependencyProperties(每个方向一个 - N、S、E、W),类型为 bool,每个都连接到 BoolToVisibilityConverter。这个概念是通过将HasDirectionDoor 属性设置为true 或false,可以在Visible 和Collapsed 之间切换门。据我所知,一切都设置正确,但它根本不起作用。如果我在BoolToVisConverterConvertConvertBack 方法上放置断点,则这些断点永远不会触发,这意味着它甚至没有到达转换器。然而,查看我所写的内容,并将其与我在各种指南中找到的内容进行比较,一切看起来都相同且正确。有人可以看一下代码吗,我确定这是我缺少的一些简单的东西,但我就是看不到它。

BoolToVis:

namespace Crawler.Converters
{
    public class BoolToVisibilityConverter : IValueConverter
    {
        public BoolToVisibilityConverter()
        {

        }

        public object Convert(object value, Type targetType, object parameter, string language)
        {
            //return (value is bool && (bool)value) ? Visibility.Visible : Visibility.Collapsed;

            if (value is bool && (bool)value)
            {
                return Visibility.Visible;
            }
            return Visibility.Collapsed;
        }

        public object ConvertBack(object value, Type targetType, object parameter, string language)
        {
            return (value is Visibility && (Visibility)value == Visibility.Visible);
        }
    }
}

用户控件 XAML:

<UserControl
    x:Class="Crawler.DungeonRoom"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:Crawler"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:BooleanToVisibility="using:Crawler.Converters"
    mc:Ignorable="d" Background="White" Height="110" Width="110"
    d:DesignHeight="110" d:DesignWidth="110">
    <UserControl.Resources>
        <BooleanToVisibility:BoolToVisibilityConverter x:Key="BoolToVis" />         
    </UserControl.Resources>
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="5" />
            <ColumnDefinition Width="25" />
            <ColumnDefinition Width="25" />
            <ColumnDefinition Width="25" />
            <ColumnDefinition Width="25" />
            <ColumnDefinition Width="5" />
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="5" />
            <RowDefinition Height="25" />
            <RowDefinition Height="25" />
            <RowDefinition Height="25" />
            <RowDefinition Height="25" />
            <RowDefinition Height="5" />
        </Grid.RowDefinitions>
        <Border Grid.Column="1" Grid.Row="1" Grid.ColumnSpan="4" Grid.RowSpan="4" Background="White" />
        <Border x:Name="westDoor" Grid.Column="0" Grid.Row="2" Grid.RowSpan="2" Background="SaddleBrown" Visibility="{Binding HasWestDoor, Converter={StaticResource ResourceKey=BoolToVis}}" />
        <Border x:Name="northDoor" Grid.Column="2" Grid.Row="0" Grid.ColumnSpan="2" Background="SaddleBrown" />
        <Border x:Name="eastDoor" Grid.Column="5" Grid.Row="2" Grid.RowSpan="2" Background="SaddleBrown" />
        <Border x:Name="southDoor" Grid.Column="2" Grid.Row="5" Grid.ColumnSpan="2" Background="SaddleBrown" />
        <Border x:Name="roomIcon" Grid.Column="4" Grid.Row="1" BorderBrush="DimGray" BorderThickness="1 0 0 1">
            <Image Source="Assets\MapTiles\Camp.png" />
        </Border>
    </Grid>
</UserControl>

用户控件 C#:

using System;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;

namespace Crawler
{
    public sealed partial class DungeonRoom : UserControl
    {
        public static readonly DependencyProperty HasWestDoorProperty =
            DependencyProperty.Register("HasWestDoor", typeof(Boolean), typeof(DungeonRoom), new PropertyMetadata(false));

        public static readonly DependencyProperty HasNorthDoorProperty =
            DependencyProperty.Register("HasNorthDoor", typeof(Boolean), typeof(DungeonRoom), new PropertyMetadata(false));

        public static readonly DependencyProperty HasEastDoorProperty =
            DependencyProperty.Register("HasEastDoor", typeof(Boolean), typeof(DungeonRoom), new PropertyMetadata(false));

        public static readonly DependencyProperty HasSouthDoorProperty =
            DependencyProperty.Register("HasSouthDoor", typeof(Boolean), typeof(DungeonRoom), new PropertyMetadata(false));

        public static readonly DependencyProperty TypeProperty =
            DependencyProperty.Register("Type", typeof(RoomType), typeof(DungeonRoom), new PropertyMetadata(0));

        public bool HasWestDoor
        {
            get { return (bool)GetValue(HasWestDoorProperty); }
            set { SetValue(HasWestDoorProperty, value); }
        }
        public bool HasNorthDoor
        {
            get { return (bool)GetValue(HasNorthDoorProperty); }
            set { SetValue(HasNorthDoorProperty, value); }
        }

        public bool HasEastDoor
        {
            get { return (bool)GetValue(HasEastDoorProperty); }
            set { SetValue(HasEastDoorProperty, value); }
        }

        public bool HasSouthDoor
        {
            get { return (bool)GetValue(HasSouthDoorProperty); }
            set { SetValue(HasSouthDoorProperty, value); }
        }

        public RoomType Type
        {
            get { return (RoomType)GetValue(TypeProperty); }
            set { SetValue(TypeProperty, value); }
        }

        public DungeonRoom()
        {
            this.InitializeComponent();
        }
    }
}

【问题讨论】:

    标签: c# uwp binding user-controls ivalueconverter


    【解决方案1】:

    您的绑定可能会失败,因为您尚未为其设置源或将BorderDataContext 设置为定义源属性的UserControl

    尝试给UserControl 一个Name 并使用ElementName 属性绑定到它:

    <UserControl .... Name="uc">
    ...
        <Border x:Name="westDoor" ... Visibility="{Binding HasWestDoor, ElementName=uc,
             Converter={StaticResource ResourceKey=BoolToVis}}" />
    

    或者使用compiled binding:

    <Border x:Name="westDoor" ... Visibility="{x:Bind HasWestDoor, Mode=OneWay,
         Converter={StaticResource ResourceKey=BoolToVis}}" />
    

    如果绑定失败,这应该会给你一个编译错误。

    【讨论】:

    • 我知道这将是一件非常简单的事情。当我读到“DataContext”时,我记得我没有这样做。我会在几分钟内测试它,但我很确定你是对的。旁注:Visual Studio 需要为缺少 DataContext 添加警告。
    • 如果你使用x:Bind,如果绑定失败,你应该得到一个编译错误。我编辑了我的答案以包括这个。在这种情况下,这可能是一个更好的选择。
    • 实际上只需将其更改为 x:Bind 即可使其按原样工作。
    • 是的,您不需要命名UserControl,但请记住将绑定的Mode 设置为OneWay,因为它默认为OneTime
    • x:Bind 内置了 BoolToVis 转换。 Visibility="{x:Bind HasWestDoor, Mode=OneWay}" 应该足够了。
    猜你喜欢
    • 2016-11-26
    • 2018-05-01
    • 2020-07-18
    • 2017-01-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-15
    • 1970-01-01
    相关资源
    最近更新 更多