所以这就是我正在反对的问题:我有一个自定义用户控件,它公开了两个绑定到我的ViewModel的依赖项属性。在我的ViewModel中,我有一个类的实例,它包含多个属性,这些属性表示与用户控件相关的值以及控制操作的项。这里有一些示例代码可以直观地解释它,所以这里是我控件的一个简单示例,它是一个Slider,它与一个允许用户锁定滑块的复选框相结合。
<custom:SliderControl IsLocked="{Binding Path=CustomClass.IsLocked, Mode=TwoWay}" SliderValue="{Binding Path=CustomClass.Value, Mode=TwoWay}" />
IsLocked和SliderValue是依赖项属性,可以有效地操作自定义控件中包含的复选框和滑块。除了绑定到我定义的类之外,所有控制函数都按预期工作。如果我创建单个属性,如在一个int属性和一个bool属性中,绑定按预期工作。但是我有五个滑块,我实际代码中的每个滑块都有五个与之相关的属性。我试图通过创建一个类来消除代码重复,以便在可重用的对象中保存这些属性,将我的25个属性缩小到5个类实例。
我的CustomClass继承了ObservableObject,并且分别具有名为IsLocked和SliderValue的bool属性和int属性。对于更多的视觉辅助,这里是它的样子:
public class CustomClass : ObservableObject
{
public const string SliderValuePropertyName = "SliderValue";
private int _sliderValue= 0;
public int SliderValue
{
get
{
return _sliderValue;
}
set
{
if (_sliderValue== value)
{
return;
}
_sliderValue= value;
RaisePropertyChanged(SliderValuePropertyName );
}
}
public const string IsCheckedPropertyName = "IsChecked";
private bool _isChecked = false;
public bool IsChecked
{
get
{
return _isChecked;
}
set
{
if (_isChecked == value)
{
return;
}
_isChecked = value;
RaisePropertyChanged(IsCheckedPropertyName);
}
}
ViewModel属性非常相似,看起来像这样,在ViewModel加载时会创建一个新的类实例:
public const string SliderOnePropertyName = "SliderOne";
private CustomClass _sliderOne;
public CustomClass SliderOne
{
get
{
return _sliderOne;
}
set
{
if (_sliderOne== value)
{
return;
}
_sliderOne= value;
RaisePropertyChanged(SliderOnePropertyName );
}
}
为什么绑定到类中属性的依赖项属性的更新不能正确更新?是因为您无法自行更新类实例属性,而是必须在发生更改时更新整个类实例?或者我是否需要在此ViewModel属性中进一步自定义setter?因为它现在正在改变滑块值或复选框永远不会点击绑定属性,并且在调试时没有任何错误。
编辑:我还在Border中包围了控件,并将Border UIElement的DataContext设置为类的DataContext,然后将更简单的路径绑定应用于底层自定义控件。然而,这对我的问题没有任何影响。我是一个本土的程序员,所以我经常在把代码放在一起时会错过任何东西,我猜这是这种情况,除非我正在尝试的东西不起作用。
非常感谢任何帮助。
编辑:所以我一直在使用自定义事件,让我知道自定义控件的特定属性何时更改,然后在我的ViewModel中连接该事件以更新现有类。这仍然有效,但仍然会创建代码重复,因为现在我必须有10个事件,每个控件有2个事件,一个用于检查滑块值何时更改,另一个用于检查复选框IsChecked值何时更改。存在此代码重复,因为您无法路由多个命令参数(例如正在操作滑块的简单字符串标识符以及您要在代码中使用的值)。这种限制意味着我不能只使用2个事件来区分在定义的方法中哪个控件正在发生变化,因为将物理控件暴露给ViewModel会破坏MVVM模式。使用类作为用户控件的datacontext使得我不关心操作什么控件,因为他们每个都有自己的类实例。使用事件会解开MVVM模式,因为现在我需要知道用户正在操纵五个控件中的哪一个。
在属性绑定中使用类不是很难。我不得不遗漏一些补救措施。
答案 0 :(得分:1)
可能只是语法错误。试试这个
{Binding Path = CustomClass.IsLocked,Mode = TwoWay}
答案 1 :(得分:1)
这是一个完整的例子:
public partial class MainPage : UserControl
{
public MainPage()
{
InitializeComponent();
this.DataContext = new ViewModel();
}
}
public class ViewModel
{
public SliderValues slv { get; private set; }
public ViewModel()
{
slv = new SliderValues();
}
}
public class SliderValues : INotifyPropertyChanged
{
bool _isLocked = false;
public bool IsLocked
{
get { return _isLocked; }
set
{
_isLocked = value;
OnPropertyChanged("IsLocked");
}
}
int _theValue = 5;
public int TheValue
{
get { return _theValue; }
set
{
_theValue = value;
OnPropertyChanged("TheValue");
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string prop)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(prop));
}
}
现在是xaml:
<UserControl x:Class="TestBindings.MainPage"
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"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="400">
<Grid x:Name="LayoutRoot" Background="White">
<Slider Height="23" HorizontalAlignment="Left" Margin="114,138,0,0" Name="slider1" VerticalAlignment="Top" Width="100"
DataContext="{Binding slv}" Value="{Binding TheValue, Mode=TwoWay}"/>
</Grid>
</UserControl>
答案 2 :(得分:0)
试试这个...... <custom:SliderControl DataContext="{Binding CustomClass}" IsLocked="{Binding IsLocked, Mode=TwoWay}" SliderValue="{Binding Value, Mode=TwoWay}" />