C# 在另一个viewmodel中执行命令?

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

我有一个从ComboBox派生的自定义DateRangeSelector控件。这是一个带有以下过滤器的下拉控件: 1.今天 2.未来三天 3.未来三周 4.自定义范围允许用户设置自定义日期范围

现在,此DateRangeSelector控件添加到另一个XAMLActivityListMenuControlView.xaml中,如下所示:

<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
}