【问题标题】:WPF: displaying XML attribute as a checkboxWPF:将 XML 属性显示为复选框
【发布时间】:2010-12-27 18:56:31
【问题描述】:

我有这个 XmlElement,并为其添加一些属性:

xmlElemMux.SetAttribute("test1", "1");
xmlElemMux.SetAttribute("test2", "0");

在将我的网格的 DataContext 设置为 xmlElemMux 之后,我可以在 xaml 中使用这样的文本框在窗口中显示它们:
TextBox Text="{Binding XPath=@test1}"
TextBox Text="{Binding XPath=@test2}"

这很好用,但我想使用复选框而不是文本框。我试过这个:

CheckBox IsChecked="{Binding XPath=@test1}"
CheckBox IsChecked="{Binding XPath=@test2}"

但是两个复选框都显示为空,并且绑定不起作用。

感谢您的帮助!

【问题讨论】:

    标签: wpf data-binding xaml checkbox


    【解决方案1】:

    我不知道这是否与您的问题有关,但目前 WPF 中的标准复选框存在一个错误 - 如果您绑定到 IsChecked 值,它只会在复选框被选中时触发,而不是在未选中时触发无论两种方式绑定等,这可能会导致一些意想不到的结果。我相信这将在 .Net v4 中得到解决,但我花了很多时间摸不着头脑。

    无论如何,我以 Ben 的示例为例,并对其进行了更多扩展,它似乎与 XElement 一起工作得很好。见下文...

    我做了一个转换器类

    public class IntToBoolConverter : IValueConverter
    {    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)    
        {
            int intValue = System.Convert.ToInt32(value);
            return (intValue != 0);  //returns true for any non-zero value                         
        }    
    
        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)    
        {
            if ((bool) value == true)
                return "1";
            else
                return "0";
    
        }
    }
    

    然后在窗口的 XAML 中放置对应的命名空间引用

    <Window.Resources>
        <local:IntToBoolConverter x:Key="CheckBoxConv"  />
    </Window.Resources>
    <Grid Name="myGrid">
        <StackPanel>
            <TextBox Text="{Binding XPath=@test1}" Height="30" Width="200"/>
            <TextBox Text="{Binding XPath=@test2}" Height="30" Width="200"/>
            <CheckBox IsChecked="{Binding XPath=@test2, Converter={StaticResource CheckBoxConv}}"/>
        </StackPanel>
    </Grid>
    

    然后进行测试,将下面的代码放在窗口后面的代码中。

        public partial class Window1 : Window
    {
        private XmlDocument xmlDoc;
        private XmlElement xmlElemMux;
    
        public Window1()
        {
            InitializeComponent();
            xmlDoc = new XmlDocument();
            xmlElemMux = xmlDoc.CreateElement("Hello");
            xmlElemMux.SetAttribute("test1", "1");
            xmlElemMux.SetAttribute("test2", "0");
    
            myGrid.DataContext = xmlElemMux;            
        }
    }
    

    如果我单击复选框或更改文本框,它似乎绑定正确,并相应地更改 xmlElemMux 的值。转换部分可以稍微整理一下……但这只是举例说明。

    【讨论】:

    • 马克,感谢您纠正我的例子!它现在按预期工作。
    • 那个local:IntToBoolConverter在抱怨没有local。
    【解决方案2】:

    这是因为“1”和“0”不是“IsChecked”的合法值。它正在寻找“真”或“假”。您需要一个值转换器来将这些 1 和 0 更改为对应的布尔值。

    例子:

    public class IntToBoolConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            int intValue = (int)value;
            return (intValue != 0);  //returns true for any non-zero value         
        }
    
        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new Exception("The method or operation is not implemented.");
        }
    }
    

    然后在你的绑定中,包含转换器:

    <CheckBox IsChecked="{Binding XPath=@test1, Converter={StaticResource IntToBoolConverter}}"/>
    <CheckBox IsChecked="{Binding XPath=@test2, Converter={StaticResource IntToBoolConverter}}"/>
    

    【讨论】:

    • 它似乎不起作用。我在窗口中添加了这个: xmlns:mynamespace="clr-namespace:WPFMyApp" 然后在我的网格中: 我的复选框: 使用调试器,我可以看到 Convert 永远不会被调用
    • 嗯,我让它与您使用的相同声明样式一起工作。我会继续玩它,看看我是否也可以让它为我打破。
    • 我明白你在说什么。我使用常规 int 属性进行快速测试,但切换到 XmlElement 会阻止它工作。我怀疑这与 XmlElement 未通知属性更改有关。如果我选中复选框,XmlElement 属性会更改,但如果我更改属性,复选框不会收到通知。
    • 如果我可以投票,我会继续并降低我的回答。 :P 我似乎也无法让它与 XmlElement 一起使用。很抱歉浪费了精力!我还尝试将“Mode=TwoWay”添加到绑定中,并尝试将转换器重写为 StringToBool 转换器,因为我开始怀疑 xml 属性将作为字符串发送,但没有任何改变。如果我找到不同的解决方案,我会更新。
    猜你喜欢
    • 1970-01-01
    • 2013-07-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-19
    • 2021-12-02
    • 1970-01-01
    相关资源
    最近更新 更多