使用情节提要来发出自定义命令。错误:故事板不可冻结
我遇到了抱怨无法冻结的故事板问题。谷歌上有很多关于此的链接,但是通过阅读这些信息,我不确定如何实现我想要的。 (即几乎只是从 IsMouseOver 属性更改执行自定义命令)。我正在使用数据模板来更改我的列表视图,使其看起来像我在以下信息中提供的链接:
我的资源字典:
<DataSourceProviders:ServiceLocatorProvider ServiceType="{x:Type Interfaces:IGestureBuilderModuleController}" x:Key="GestureController"/>
<Converters:IsGestureBeingBuiltConverter x:Key="IsGestureBeingBuildConverter" />
我的 UI 看起来像:
<ListView.ItemContainerStyle>
<Style TargetType="{x:Type ListViewItem}">
<Style.Triggers>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding IsMouseOver}" Value="True" />
<Condition Binding="{Binding Path=CurrentGestureState, Converter={StaticResource IsGestureBeingBuildConverter}}" Value="True" />
</MultiDataTrigger.Conditions>
<!--TODO:Need to add a button to this control. Then use the buttons event to trigger command.-->
<MultiDataTrigger.ExitActions>
<BeginStoryboard>
<StoryBoard:CommandTimeline StoryBoard:CommandStoryboard.Command="{Binding Source={StaticResource ResourceKey=GestureController}, Path=AddToGestureCommand}" />
</BeginStoryboard>
</MultiDataTrigger.ExitActions>
</MultiDataTrigger>
</Style.Triggers>
</Style>
</ListView.ItemContainerStyle>
我的转换器看起来像:
[ValueConversion(typeof(GestureState), typeof(bool))]
public class IsGestureBeingBuiltConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return Equals(value, GestureState.BeingConstructed);
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
我的 GestureState 枚举看起来像:
public enum GestureState
{
Finished,
BeingConstructed
}
我的手势控制器/命令看起来像:
public class GestureBuilderModuleController : ModuleController, IGestureBuilderModuleController
{
public ICommand AddToGestureCommand
{
get { return new DelegateCommand<GestureBuilderViewModel>(viewModel => viewModel.AddToGesture = true); }
}
}
我的视图模型如下所示:
public GestureableItemViewModel ItemBeingAdded { get; set; }
public virtual bool AddToGesture
{
get { return false; }
set
{
if (ItemBeingAdded == null) return;
if(CurrentGestureState != GestureState.BeingConstructed) return;
SelectedItems.Add(ItemBeingAdded);
}
}
我得到的异常是:
InvalidOperation:无法冻结故事板。
我的用户界面看起来像这样:
当前的理解:
通过阅读,我了解到故事板需要可冻结,以便在未冻结的线程之间快速访问。
我的问题是如何以可冻结的方式进行绑定或使用替代方法实现我想要的效果。我的核心问题是,我想在捕获手势时将鼠标悬停在列表项上时引发自定义命令或事件。
I have having issues with a storyboard that is complaining about being unfreezable. There are alot of links on google about this, however I am not sure from reading that information how I can achieve what I want. (ie pretty much just execute a custom command from IsMouseOver property change). I am using data templating to change my listview to look like the link I have provided in the information below:
My resource dictionary:
<DataSourceProviders:ServiceLocatorProvider ServiceType="{x:Type Interfaces:IGestureBuilderModuleController}" x:Key="GestureController"/>
<Converters:IsGestureBeingBuiltConverter x:Key="IsGestureBeingBuildConverter" />
My UI looks like:
<ListView.ItemContainerStyle>
<Style TargetType="{x:Type ListViewItem}">
<Style.Triggers>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding IsMouseOver}" Value="True" />
<Condition Binding="{Binding Path=CurrentGestureState, Converter={StaticResource IsGestureBeingBuildConverter}}" Value="True" />
</MultiDataTrigger.Conditions>
<!--TODO:Need to add a button to this control. Then use the buttons event to trigger command.-->
<MultiDataTrigger.ExitActions>
<BeginStoryboard>
<StoryBoard:CommandTimeline StoryBoard:CommandStoryboard.Command="{Binding Source={StaticResource ResourceKey=GestureController}, Path=AddToGestureCommand}" />
</BeginStoryboard>
</MultiDataTrigger.ExitActions>
</MultiDataTrigger>
</Style.Triggers>
</Style>
</ListView.ItemContainerStyle>
My converter looks like:
[ValueConversion(typeof(GestureState), typeof(bool))]
public class IsGestureBeingBuiltConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return Equals(value, GestureState.BeingConstructed);
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
My GestureState Enum looks like:
public enum GestureState
{
Finished,
BeingConstructed
}
My Gesture controller/command looks like:
public class GestureBuilderModuleController : ModuleController, IGestureBuilderModuleController
{
public ICommand AddToGestureCommand
{
get { return new DelegateCommand<GestureBuilderViewModel>(viewModel => viewModel.AddToGesture = true); }
}
}
My viewmodel looks like:
public GestureableItemViewModel ItemBeingAdded { get; set; }
public virtual bool AddToGesture
{
get { return false; }
set
{
if (ItemBeingAdded == null) return;
if(CurrentGestureState != GestureState.BeingConstructed) return;
SelectedItems.Add(ItemBeingAdded);
}
}
The exception I am getting is:
InvalidOperation: Cannot freeze storyboard.
My UI looks LIKE this:
Current understanding:
I understand from reading that storyboards need to be freezable for quick access across threads where they are unfrozen.
My Question is how can I make my binding in a way that it is freezable OR achieve what I want using an alternate approach. My core problem is that I want to raise a custom command or event when mousing over a listitem when capturing a gesture.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
你不需要故事板。在 Multidatatrigger 中,使用 OneWayToTarget DataBinding 在 ViewModel 中设置属性。当触发条件满足时,将调用该属性的设置器。在该设置器中,您可以调用“this.AddToGesture = true”。
You don't need Storyboard. In your Multidatatrigger, use a OneWayToTarget DataBinding to set a property in your ViewModel. That property's setter will be invoked when the trigger condition meets. In that setter you can call "this.AddToGesture = true".