WPF 自定义用户控件绑定在列表视图中始终返回 false

Posted

技术标签:

【中文标题】WPF 自定义用户控件绑定在列表视图中始终返回 false【英文标题】:WPF Custom user control binding always return false in listview 【发布时间】:2021-10-22 13:51:30 【问题描述】:

我最近开始使用 WPF,所以我并不了解所有内容。 我的 Xaml 文件中有一个列表视图,其中列出了某个类的对象。

我创建了一个自定义用户控件(切换按钮)来切换对象的布尔属性。 以前,我使用复选框,一切正常。

现在绑定总是返回 False。

我不知道如何让它工作

我的班级:

    public class Macro : INotifyPropertyChanged

    public event PropertyChangedEventHandler PropertyChanged;

    public const int EDITPIECE = 1, WALLREDITPIECE = 2, DORMIR = 3, NO_ACTION = 0;

    public static double speed = 0;

    private bool _status;
    public bool status 
        get 
            return _status;
        
        set 
            if (value != this._status)
            
                this._status = value;
                NotifyPropertyChanged();
            
        
    
    private string _key;
    public string key 
        get
        
            return _key;
        
        set
        
            if (value != this._key)
            
                this._key = value;
                NotifyPropertyChanged();
            
        
    

    public string _macroname  get; set; 
    public int _action  get; set; 

    ...
    

我的列表视图:

        <ListView Margin="10" Name="lvDataBinding" Width="auto"  Background="Transparent" Foreground="white" BorderThickness="0">
        
        <ListView.ItemTemplate>
            <DataTemplate>
                <WrapPanel>
                    <TextBlock Text="Binding _macroname" FontWeight="Bold" />
                    <TextBlock Text="  " />
                    <!-- Checkbox works fine --> <CheckBox IsChecked="Binding status , Mode=TwoWay, UpdateSourceTrigger=PropertyChanged" Checked="CheckBoxChanged" Unchecked="CheckBoxChanged"/>
                    <!-- Custom Toggle not working --> <theme:OnOff Height="24" Width="40" Toggle="Binding status, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged"/>
                    <TextBlock Text=" key : " />
                    <Button x:Name="keybutton" Content="Binding key, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged" Click="keybutton_Click"/>
                </WrapPanel>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>

自定义用户控件:

public static readonly DependencyProperty ToggleProperty = DependencyProperty.Register("Toggle", typeof(bool), typeof(OnOff), new PropertyMetadata(false));

    public bool Toggle
    
        get  return (bool)base.GetValue(OnOff.ToggleProperty); 
        set  base.SetValue(OnOff.ToggleProperty, value); 
    

如果填满了我的清单:

public partial class Page1 : Page

    private List<Macro> listMacroConfig = new List<Macro>();
    public Page1()
    
        InitializeComponent();
        listMacroConfig = ((App)Application.Current)._macros;
        lvDataBinding.ItemsSource = listMacroConfig;
    

【问题讨论】:

您是否明确设置了 UserControl 的 DataContext,例如在其 XAML 或代码后面?那将是问题所在。您如何注意到绑定不起作用?没有 PropertyChangedCallback,属性的可视化可能不起作用(你没有向我们展示那部分)。 请注意,GetValue(ToggleProperty) 等同于 base.GetValue(OnOff.ToggleProperty) 您的 OnOff 类是否继承自 WPF ToggleButton 类?如果没有,您将需要实现让鼠标和键盘输入自行更改ToggleProperty 值的代码。您的依赖属性将绑定到视图模型属性,但它们都不会因为它们存在而在用户交互时改变。您需要在控件模板中连接功能... 此外,即使OnOff 将继承自ToggleButton,点击其 UI 表面仍不会转换为对 Toggle 设置器的调用。点击仍然只会切换IsChecked 属性。 【参考方案1】:

我将 onOff 控件更改为:

public partial class OnOff : UserControl 

    static Thickness LeftSide = new Thickness(-16, 0, 0, 0);
    static Thickness RightSide = new Thickness(16, 0,0 , 0);
    
    static SolidColorBrush gray = new SolidColorBrush(Color.FromRgb(139,139,144));
    static SolidColorBrush red = new SolidColorBrush(Color.FromRgb(179, 34, 54));
    static SolidColorBrush transparent = new SolidColorBrush(Color.FromArgb(0,0, 0, 0));



    public static readonly DependencyProperty ToggleProperty = DependencyProperty.Register(nameof(Toggle), typeof(bool), typeof(OnOff), new PropertyMetadata(false, TooglePropertyChangedCallback));


    public bool Toggle
    
        get  return (bool)base.GetValue(OnOff.ToggleProperty); 
        set  base.SetValue(OnOff.ToggleProperty, value); 
    

    public OnOff()
    
        InitializeComponent();
    


    private void dot_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    
        Toggle = !Toggle;

    



    //  This is the callback that will update the background
    private static void TooglePropertyChangedCallback(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)
    
        var target = (OnOff)dependencyObject;

        target.back.Fill = (target.Toggle ? red : transparent);
        target.dot.Margin = (target.Toggle ? RightSide : LeftSide);
        target.dot.Fill = (target.Toggle ? red : gray);

    




现在完美运行,有什么可以改进的吗?

【讨论】:

以上是关于WPF 自定义用户控件绑定在列表视图中始终返回 false的主要内容,如果未能解决你的问题,请参考以下文章

WPF 在 GridViewColumn.CellTemplate 的 DataTemplate 中绑定 UserControl 属性

wpf 自定义控件的自定义属性的数据绑定问题

自定义用户控件的 DependencyProperty 绑定未在更改时更新

设置绑定到 WPF 用户控件内的自定义 DependencyProperty

WPF 自定义列表筛选 自定义TreeView模板 自定义ListBox模板

我的 WPF 自定义控件 Datacontext 正在取代父母