gpt4 book ai didi

c# - UserControl 绑定(bind)到 observablecollection 不起作用

转载 作者:行者123 更新时间:2023-11-30 21:41:34 24 4
gpt4 key购买 nike

我环顾四周,但仍然找不到解决方案......

我制作了一个 UserControl,它基本上是一个 slider ,但几乎没有自定义功能。

public partial class CustomSlider : UserControl
{
public CustomSlider()
{
InitializeComponent();
this.DataContext = this;

CMiXSlider.ApplyTemplate();
Thumb thumb0 = (CMiXSlider.Template.FindName("PART_Track", CMiXSlider) as Track).Thumb;
thumb0.MouseEnter += new MouseEventHandler(thumb_MouseEnter);
}

private void thumb_MouseEnter(object sender, MouseEventArgs e)
{
if (e.LeftButton == MouseButtonState.Pressed && e.MouseDevice.Captured == null)
{
MouseButtonEventArgs args = new MouseButtonEventArgs(e.MouseDevice, e.Timestamp, MouseButton.Left);
args.RoutedEvent = MouseLeftButtonDownEvent;
(sender as Thumb).RaiseEvent(args);
}
}

public static readonly DependencyProperty ValueProperty =
DependencyProperty.Register("Value", typeof(double), typeof(CustomSlider), new PropertyMetadata(0.0));
public double Value
{
get { return (double)this.GetValue(ValueProperty); }
set { this.SetValue(ValueProperty, value); }
}
}

XAML:

<UserControl x:Class="CMiX.CustomSlider"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:CMiX"
mc:Ignorable="d"
d:DesignHeight="139.8" d:DesignWidth="546.2">
<UserControl.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/CMiX_UserControl;component/RessourceDictionnaries/Brushes/GenericBrushes.xaml"/>
<ResourceDictionary Source="/CMiX_UserControl;component/RessourceDictionnaries/Styles/BaseSliderStyle.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</UserControl.Resources>
<Grid>
<Slider x:Name="CMiXSlider" Style="{StaticResource BaseSliderStyle}"
Value="{Binding Value, Mode=TwoWay, RelativeSource={RelativeSource AncestorType={x:Type local:CustomSlider}}}"
IsMoveToPointEnabled="True" Minimum="0.0" Maximum="1.0"/>
</Grid>

然后我在另一个 UserControl 中使用它:

<CMiX:CustomSlider x:Name="SliderTest" Grid.Row="2" Value="{Binding ChannelsAlpha[0], Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>

我正在尝试绑定(bind)到这个 ObservableCollection(同一个 slider 将被使用 6 次):

private ObservableCollection<double> _ChannelsAlpha = new ObservableCollection<double>(new[] { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 });
public ObservableCollection<double> ChannelsAlpha
{
get { return _ChannelsAlpha; }
set { _ChannelsAlpha = value; }
}

问题是,绑定(bind)没有以任何方式发生。我特别不明白的是,如果我使用这个标准 slider :

<Slider x:Name="Ch0_Alpha" Margin="1" IsMoveToPointEnabled="True" Minimum="0.0" Maximum="1.0" Orientation="Horizontal" Value="{Binding DataContext.ChannelsAlpha[0], ElementName=Ch0_Alpha, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>

然后它按预期工作。

最佳答案

你不能绑定(bind)到任何东西,因为你非常小心地破坏了你的 DataContext:

this.DataContext = this;

不要那样做。要绑定(bind)到 UserControl 本身的属性,请使用 RelativeSource 绑定(bind),例如...与您已经使用的完全一样:

<Slider 
x:Name="CMiXSlider"
Style="{StaticResource BaseSliderStyle}"
Value="{Binding Value, Mode=TwoWay, RelativeSource={RelativeSource AncestorType={x:Type local:CustomSlider}}}"
IsMoveToPointEnabled="True"
Minimum="0.0"
Maximum="1.0"
/>

我没有看到您在 UserControl XAML 中使用 DataContext 的任何地方,所以我只是在构造函数中删除该行并去喝杯啤酒。

好吧,首先,为了良好的形式,我会去掉构造函数中的模板内容,并将其移至 OnApplyTemplate:

public CustomSlider()
{
InitializeComponent();
}

public override void OnApplyTemplate()
{
Thumb thumb0 = (CMiXSlider.Template.FindName("PART_Track", CMiXSlider) as Track).Thumb;
thumb0.MouseEnter += new MouseEventHandler(thumb_MouseEnter);
}

然后是啤酒。

附言以下是调试绑定(bind)的方法:

Value="{Binding ChannelsAlpha[0], PresentationTraceSources.TraceMode=High, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"

添加 PresentationTraceSources.TraceMode=High,然后在运行时在 VS 中观察输出窗口。它会告诉您尝试解析绑定(bind)所采取的所有步骤。在这种情况下,它将告诉您它正在 CMiX:CustomSlider 实例上而不是 View 模型上寻找 ChannelIsAlpha。这是您的线索,即问题是通过删除 DataContext 的继承值而产生的。在您的构造函数中,this.DataContext 是父 View 的 View 模型,直到您将其设置为 this(弹出断点并查看)。

这就是为什么我们中的一些脾气暴躁的老人对不设置 this.DataContext = this; 有这样的毛刺。首先你在它相对无害的情况下这样做,然后你开始认为这只是必要的样板,然后你就到了。事实上,永远 都没有必要。

Bindings 和 DataContext 很难习惯,因为有这种隐含的事情在发生。一开始我觉得很奇怪。请记住,假设默认情况下,所有绑定(bind)都希望绑定(bind)到 View 模型,并且您应该始终能够假设无论您身在何处,DataContext 都将是 View 模型。永远不要显式设置 DataContext

绑定(bind)到 View 模型以外的任何东西是一个特例:RelativeSource={RelativeSource AncestorType=FooBar}, Source={StaticResource WhateverKey}, ElementName=FooBarListBox RelativeSource={RelativeSource Self} 或其他。

关于c# - UserControl 绑定(bind)到 observablecollection 不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43234260/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com