C# 在另一个viewmodel中执行命令?
我有一个从ComboBox派生的自定义DateRangeSelector控件。这是一个带有以下过滤器的下拉控件: 1.今天 2.未来三天 3.未来三周 4.自定义范围允许用户设置自定义日期范围 现在,此DateRangeSelector控件添加到另一个XAMLActivityListMenuControlView.xaml中,如下所示:C# 在另一个viewmodel中执行命令?,c#,wpf,xaml,mvvm,icommand,C#,Wpf,Xaml,Mvvm,Icommand,我有一个从ComboBox派生的自定义DateRangeSelector控件。这是一个带有以下过滤器的下拉控件: 1.今天 2.未来三天 3.未来三周 4.自定义范围允许用户设置自定义日期范围 现在,此DateRangeSelector控件添加到另一个XAMLActivityListMenuControlView.xaml中,如下所示: <DateRangeSelector:DateRangeSelectorControl x:Name="DateRangeSelector" Gr
<DateRangeSelector:DateRangeSelectorControl x:Name="DateRangeSelector"
Grid.Column="1"
Margin="10 0 0 0"
HorizontalAlignment="Left"
VerticalAlignment="Center"
AutomationProperties.AutomationId="AID_TaskListDateRangeSelector"
DateRangeUpdatedCmd="{Binding Path=DateRangeSelectionUpdatedCommand}"
TodayDateUpdatedCmd="{Binding Path=TodayDateUpdatedCommand}"
FontSize="{StaticResource TaskListMenuFontSize}"
RangeOptions="{Binding Path=DateRangeSelectionOptions,
Mode=OneTime}"
SelectedDateRange="{Binding Path=SelectedRange,
Mode=TwoWay}"
Visibility="{Binding Path=ShowFilterOptions,
Converter={StaticResource boolToVisibility}}" />
从上面的代码可以明显看出,我在DateRangeSelector中创建了一个命令TodayDateUpdateCmd,用于在系统日期更改时更新此控件中的TodayDateUpdated筛选器,并绑定到ActivityListMenuControlViewModel中的命令TodayDateUpdatedCommand。
更新日期的代码在DateRangeSelector本身的SetDateValues方法中。
我只是对如何从ActivityListMenuControlViewModel执行此方法感到困惑?
请帮忙
更新:
DateRangeSelector只是一个没有视图/视图模型的类。代码如下:
public class DateRangeSelectorControl : ComboBox, INotifyPropertyChanged
{
public static readonly DependencyProperty TodayDateUpdateCmdProperty = DependencyProperty.Register("TodayDateUpdatedCmd", typeof(ICommand), typeof(DateRangeSelectorControl),
new PropertyMetadata(null));
public ICommand TodayDateUpdatedCmd
{
get { return (ICommand)this.GetValue(TodayDateUpdateCmdProperty); }
set
{
this.SetValue(TodayDateUpdateCmdProperty, value);
}
}
/// <summary>
///
/// </summary>
private void SetDateValues()
{
DateTime todaysDate = DateTime.Now;
TodayText = Utility.GetStringFromResource("TodayLabel") + " (" + todaysDate.ToShortDateString() + ")";
NextThreeDaysText = Utility.GetStringFromResource("NextThreeDaysLabel") + " (" + todaysDate.ToShortDateString() + " - " + todaysDate.AddDays(3).ToShortDateString() + ")";
NextWeekText = Utility.GetStringFromResource("NextWeekLabel") + " (" + todaysDate.ToShortDateString() + " - " + todaysDate.AddDays(7).ToShortDateString() + ")";
SetCustomDateRangeText();
}
}
从上面的代码中可以明显看出,我首先注册了一个依赖属性TodayDateUpdateCmdProperty和命令属性TodayDateUpdateCmd,该属性在ActivityListMenuControlView.xaml中使用,如xaml代码段中所示。此外,我需要在DateRangeSelector类中执行SetDateValues方法来更新今天的日期。
现在请帮助我如何实现这一点
更新:
根据@GazTheDestroyer的建议,我对代码进行了更改,现在没有使用任何命令。但现在获得运行时XamlParseException,详细信息如下:
'对与指定绑定约束匹配的类型'VMS.Nexus.Client.Common.Controls.DateRangeSelector.DateRangeSelectorControl'调用构造函数时引发异常。'行号'45'和行位置'14'
内部异常:
{默认值类型与属性“TodayDate”的类型不匹配。}
此异常在我创建DateRangeSelector的ActivityListMenuControlView.xaml中引发。
请帮助在编写WPF和MVVM时,开发人员通常使用委托ICommand的形式,我们可以在视图模型中声明。您可以在MSDN页面的中继命令逻辑部分找到常用中继命令的实现细节。在这里关于堆栈溢出的问题中,您可以找到一个使用它的基本示例 因此,可以在视图模型中定义ICommand实例,并将它们绑定到控件。对于DateRangeSelector,您可以简单地声明ICommand类型的DependencyProperty,并从视图模型中绑定到该属性的数据。。。也许是这样的:
<DateRangeSelector:DateRangeSelectorControl TodayDateUpdatedCmd="{Binding Command}">
...
</DateRangeSelector:DateRangeSelectorControl>
更新>>>
简单地说,不需要在这个或WPF中的几乎任何实例中扩展ComboBox类。请参阅MSDN上的页面,了解有关为什么不需要执行此操作的更多信息
所以基本的想法是,将功能从组合框移动到另一个类。。。视图模型类。然后,您可以将数据绑定到组合框并提供功能。在WPF中,我们操作数据,而不是UIElements。因此,与其在控件中定义所有“过滤器”,不如在代码中定义它们
首先,您需要一个包含可用日期的集合属性:
public ObservableCollection<DateTime> AvailableDates
{
get { return availableDates; }
set { availableDates = value; NotifyPropertyChange("AvailableDates"); }
}
希望您现在有一个更好的想法。命令应该由控件触发,而不是用作您似乎正在尝试的控件的通知机制 如果控件需要对某些变化的变量作出反应,那么它应该公开DependencyProperty并对该变量的变化作出反应。例如,在DateRangeSelectorControl的代码中
然后,您的ViewModel只需公开一个可以绑定到此DependencyProperty的TodaysDate属性。我没有为DateRangeSelector创建任何ViewModel。它仅在Themes\Generic.xaml中定义,仅在.cs fileDateRangeSelector.csI know中定义。我发布的代码位于DateRangeSelector.cs中,而不是视图模型。我提到的ViewModel是ActivityListMenuControlViewModel或类似的。然后,ViewModel可以简单地公开可以绑定到此DependencyProperty的TodaysDate属性。在您发布这一行时,如果我没有任何viewmodel,如何公开TodaysDate属性。如果您能在DateRangeSelector和ActivityListMenuControlViewModel的上下文中提供一些代码片段来帮助我,那就太好了!正如我在上一篇评论中解释的,今天的日期将由ActivityListMenuControlViewModel公开。谢谢。我仍然有一个疑问,我已经在ActivityListMenuControlView.xaml中使用ActivityListMenuControlViewModel中定义的ICommand TodayDateDatedRangeSelector命令将绑定提供给了TodayDateDateRangeSelector,那么我现在应该怎么做呢?任何代码都会非常有用。请参阅我为DateRangeSelector代码提供的更新。请注意,我没有为相同的代码定义任何viewmodel。如果您能在DateRangeSelector和ActivityListMenuControlViewModel的上下文中提供一些代码片段来帮助我,那就太好了!
public ObservableCollection<DateTime> AvailableDates
{
get { return availableDates; }
set { availableDates = value; NotifyPropertyChange("AvailableDates"); }
}
public FilterType FilterType
{
get { return filterType; }
set
{
filterType = value;
NotifyPropertyChange("FilterType");
FillAvailableDatesDependantOnFilterType();
}
}
private void FillAvailableDatesDependantOnFilterType()
{
AvailableDates = new ObservableCollection<DateTime>();
if (FilterType == "Today") AvailableDates.Add(DateTime.Now.Date);
...
}
public static readonly new DependencyProperty TodaysDateProperty=
DependencyProperty.Register("TodaysDate", typeof(DateTime), typeof(DateRangeSelectorControl), new PropertyMetadata(null, TodaysDateChanged));
public new DateTime TodaysDate
{
get { return (DateTime)GetValue(TodaysDateProperty); }
set { SetValue(TodaysDateProperty, value); }
}
private static void TodaysDateChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
((DateRangeSelectorControl)d).TodaysDateChanged((DateTime)e.NewValue);
}
private void TodaysDateChanged(DateTime newDate)
{
//update your control here
}