我正在为项目编写自定义控件。该控件将包含下拉组合框和数据网格。该控件将在整个项目中使用。在控件上,我将SelectedDate和SelectedDateChangedCommand作为依赖项属性公开。当用户选择日期时,主程序模型将更新其相关日期的信息列表。
当我在项目中使用该控件时,数据(SelectedDate)应来自模型,但命令(SelectedDateChangedCommand)应来自ViewModel。如何将数据绑定到Model和ViewModel的命令?
基本上,如果我想绑定同一个按钮的内容AND命令,我该怎么办?
修改 好吧,我不认为我能很好地解释这一点。我没有使用框架或模板或类似的东西。也许我的问题是提到UserControl。我的问题不在于编写UserControl。我的问题来自控制之外。我没有代码示例,因为这是我的问题:我该怎么做?如果我有某种代码,那就像这样:
<Button Content="{Binding Model.SelectedDate]" Command="{Binding ViewModel.SelectedDateChanged}" />
如何在两个不同类的控件上绑定两个属性?
哇,甚至询问问题在WPF中都很难。 :)
答案 0 :(得分:0)
好的,如果我了解你,你想创建一个cc。然后在你的vm上运行绑定到DateTime到你的SelectedDate,并从控件到vm调用命令?我在这里为你做了一个简单的例子,我希望我能正确理解你。我通过使用datepicker简化了这个例子。我在这里使用galasoft MVVM Light。将内容更改为您想要的内容。希望我没有让你完全错误:)
<强> Generic.xaml 强>
<Style TargetType="{x:Type local:YourCustControl}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:YourCustControl}">
<Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<Grid >
<DatePicker x:Name="PART_DatePicker"
SelectedDate="{Binding Path=YourDateTime, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged,
RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:YourCustControl}}}"/>
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<强> CustControl 强>
[TemplatePart(Name = "PART_DatePicker", Type = typeof (DatePicker))]
public class YourCustControl : Control
{
public static readonly DependencyProperty SelectedDateChangedCommandProperty = DependencyProperty.Register("SelectedDateChangedCommand", typeof (ICommand), typeof (YourCustControl), new PropertyMetadata(null));
public static readonly DependencyProperty YourDateTimeProperty = DependencyProperty.Register("YourDateTime", typeof (DateTime), typeof (YourCustControl), new PropertyMetadata(null));
private DatePicker datePicker;
static YourCustControl()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof (YourCustControl), new FrameworkPropertyMetadata(typeof (YourCustControl)));
}
public ICommand SelectedDateChangedCommand
{
get { return (ICommand) GetValue(SelectedDateChangedCommandProperty); }
set { SetValue(SelectedDateChangedCommandProperty, value); }
}
public DateTime YourDateTime
{
get { return (DateTime) GetValue(YourDateTimeProperty); }
set { SetValue(YourDateTimeProperty, value); }
}
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
datePicker = (DatePicker) Template.FindName("PART_DatePicker", this);
if (datePicker != null)
{
datePicker.SelectedDateChanged += datePicker_SelectedDateChanged;
}
}
private void datePicker_SelectedDateChanged(object sender, SelectionChangedEventArgs e)
{
// Execute the command
if (SelectedDateChangedCommand != null && SelectedDateChangedCommand.CanExecute(e) && !e.Handled)
SelectedDateChangedCommand.Execute(e);
}
}
<强>视图模型强>
// replace with whatever, like extend Galasoft's ViewModelBase
public class YourViewModelBase : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
[NotifyPropertyChangedInvocator] // Remove if no R#
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}
}
public class YourViewModel : YourViewModelBase
{
private DateTime dateTime;
public DateTime DateTime
{
get { return dateTime; }
set
{
if (value.Equals(dateTime)) return;
dateTime = value;
OnPropertyChanged();
}
}
public ICommand SelectedDateChangedCommand { get; set; }
public YourViewModel()
{
SelectedDateChangedCommand = new RelayCommand<SelectionChangedEventArgs>(OnSelectedDateChanged);
}
private void OnSelectedDateChanged(SelectionChangedEventArgs e)
{
if (e != null)
e.Handled = true; // dirty hack
// do stuff here
}
}
最后你的xaml
<Grid>
<local:YourCustControl SelectedDateChangedCommand="{Binding SelectedDateChangedCommand}"
YourDateTime="{Binding DateTime, Mode=TwoWay}"/>
</Grid>
希望它有所帮助!
干杯