好的......这让我挠头.我有两个WPF控件 - 一个是用户控件,另一个是自定义控件.我们称他们为UserFoo和CustomFoo.在CustomFoo的控件模板中,我使用UserFoo的一个实例,这是一个命名的部分,所以我可以在应用模板后到达它.这很好.
现在,UserFoo和CustomFoo都有一个Text定义的属性(独立地,即不是使用AddOwner的共享DP.不要问...)这两个都被声明为......
public static readonly DependencyProperty TextProperty = DependencyProperty.Register(
"Text",
typeof(string),
typeof(UserFoo), // The other is CustomFoo
new FrameworkPropertyMetadata(
null,
FrameworkPropertyMetadataOptions.BindsTwoWayByDefault,
null,
null,
true,
UpdateSourceTrigger.PropertyChanged
)
);
Run Code Online (Sandbox Code Playgroud)
请特别注意,模式设置为TwoWay,UpdateSourceTrigger设置为PropertyChanged,两者都设置为.
因此,在CustomFoo的样式模板中,我想将CustomFoo的Text属性绑定为内部UserFoo的Text属性的源.通常,这很容易.你只需将UserFoo的文本属性设置为"{TemplateBinding Text}",但由于某种原因,它只采用一种方式(即从FreeFoo中正确设置UserFoo,但不是相反),即使再次,两个DP都设置为双向!但是,当使用相对源绑定而不是模板绑定时,它工作得很好!嗯......哇?
// This one works
Text="{Binding Text, RelativeSource={RelativeSource AncestorType={local:CustomFoo}}, Mode=TwoWay}"
// As does this too...
Text="{Binding Text, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay}"
// But not this one!
Text="{TemplateBinding Text}"
Run Code Online (Sandbox Code Playgroud)
什么给出了什么?我错过了什么?
我有一个带有字符串属性和List属性的简单类,我实现了INofityPropertyChanged事件,但是当我对字符串List执行.Add时,此事件未被命中,因此我的ListView中显示的Converter未被命中.我猜测属性已更改未被添加到列表中....如何实现此方法以获取该属性更改事件命中???
我需要使用其他类型的收藏吗?!
谢谢你的帮助!
namespace SVNQuickOpen.Configuration
{
public class DatabaseRecord : INotifyPropertyChanged
{
public DatabaseRecord()
{
IncludeFolders = new List<string>();
}
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
protected void Notify(string propName)
{
if (this.PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propName));
}
}
#endregion
private string _name;
public string Name
{
get { return _name; }
set
{
this._name = value;
Notify("Name");
}
}
private List<string> _includeFolders;
public List<string> IncludeFolders
{
get { return _includeFolders; }
set
{
this._includeFolders = value; …Run Code Online (Sandbox Code Playgroud) 我有一个绑定到依赖属性的TextBox,我已经实现了一个PropertyChangedCallBack函数,当文本更改时我需要调用textbox.ScrollToEnd()但是我不能因为PropertChanged函数需要是静态的,有没有办法绕过这个?
static FrameworkPropertyMetadata propertyMetaData = new FrameworkPropertyMetadata("MyWindow",
FrameworkPropertyMetadataOptions.BindsTwoWayByDefault,
new PropertyChangedCallback(TextProperty_PropertyChanged));
public static readonly DependencyProperty TextProperty = DependencyProperty.Register("TextProperty", typeof(string), typeof(OutputPanel),
propertyMetaData);
private void TextProperty_PropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
{
textbox.ScrollToEnd(); //An object reference is required for the non-static field.
}
public string Text
{
get
{
return this.GetValue(TextProperty) as string;
}
set
{
this.SetValue(TextProperty, value);
//textbox.ScrollToEnd(); // I originally called it here but I think it should be in the property changed function.
}
}
Run Code Online (Sandbox Code Playgroud)
谢谢,
埃蒙·
这是一个非常简单的问题,但我想知道是否有人可以解释第4行实际上在做什么?所以第一行给处理程序一个事件.我真的不知道在什么情况下处理程序将返回null或最后一行的作用.
当你传递处理程序时你的对象和属性发生了变化,它对它们有什么作用?
PropertyChangedEventHandler handler = PropertyChanged; //property changed is the event
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(name));
}
Run Code Online (Sandbox Code Playgroud)
我假设我使用它来获取此代码,但我想了解它正在做什么.
我试图编写一个类来避免像"RaisePropertyChanged"这样的方法.我知道我可以从具有该实现的类继承,但在某些情况下我不能.我尝试使用扩展方法,但Visual Studio抱怨.
public static class Extension
{
public static void RaisePropertyChanged(this INotifyPropertyChanged predicate, string propertyName)
{
if (predicate.PropertyChanged != null)
{
predicate.PropertyChanged(propertyName, new PropertyChangedEventArgs(propertyName));
}
}
}
Run Code Online (Sandbox Code Playgroud)
它说:
"事件' System.ComponentModel.INotifyPropertyChanged.PropertyChanged'只能出现在+ =或 - =的左侧 "
c# wpf extension-methods propertychanged inotifypropertychanged
我有一个文本框,其Text属性具有TwoWay MultiBinding,UpdateSourceTrigger设置为PropertyChanged.第一个Binding是一个依赖属性(Value),它有一个PropertyChangedCallBack函数,可以将值四舍五入到一个小数位.
文本框的目的是在用户键入时执行舍入,而不是在文本框失去焦点时执行舍入,因此将UpdateSourceTrigger设置为PropertyChanged.
我遇到的问题是,如果输入的文本不会导致值更改,则Text属性和Value将变得不同步.仅当舍入操作导致值更改时,文本才会动态更新.例如,如果Text和Value都是123.4并且用户在此之后键入1,则Value将四舍五入为相同的值(123.4),但Text显示为123.41.但是,如果在4之后键入9,则值向上舍入为123.5.由于这个实际的变化,文本然后更新为相同(123.5).
是否有任何方法强制文本框从其源更新,即使源自上次触发后没有更改?我尝试过使用BindingExpressionBase.UpdateTarget()但这仅在UpdateSourceTrigger设置为Explicit时有效,不能用作在可以调用UpdateTarget的合适时间之前不再更新的值(例如TextInput处理程序).我已经尝试过其他方法,例如从绑定值显式更新Text值,暂时强制实际更改为Value以调用更新,但这些"hacks"要么不起作用,要么导致其他问题.
任何帮助将不胜感激.
代码如下.
<TextBox>
<TextBox.Text>
<MultiBinding Converter="{local:NumberFormatConverter}"
UpdateSourceTrigger="Explicit"
Mode="TwoWay">
<Binding Path="Value"
RelativeSource="{RelativeSource AncestorType={x:Type Window}}"
Mode="TwoWay" />
</MultiBinding> …Run Code Online (Sandbox Code Playgroud) binding textbox updatesourcetrigger propertychanged multibinding
我有2个属性(WPF控件):HorizontalOffset和VerticalOffset(都是公共Double的).每当这些属性发生变化时,我想调用一个方法.我怎样才能做到这一点?我知道一种方法 - 但我很确定这不是正确的方法(使用DispatcherTimer非常短的刻度间隔来监控属性).
编辑更多背景:
这些属性属于telerik scheduleview控件.
我有一个用户控件,它公开一个名为VisibileItems的DependencyProperty每次该属性更新时,我需要触发另一个事件.为此,我添加了一个带有PropertyChangedCallback事件的FrameworkPropertyMetadata.
出于某种原因,此事件仅被调用一次,并且在下次VisibleItems更改时不会触发.
XAML:
<cc:MyFilterList VisibleItems="{Binding CurrentTables}" />
Run Code Online (Sandbox Code Playgroud)
CurrentTables是MyViewModel上的DependencyProperty.CurrentTables经常变化.我可以将另一个WPF控件绑定到CurrentTables,我看到了UI中的更改.
这是我使用PropertyChangedCallback连接VisibleItems的方式
public static readonly DependencyProperty VisibleItemsProperty =
DependencyProperty.Register(
"VisibleItems",
typeof(IList),
typeof(MyFilterList),
new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.AffectsRender, new PropertyChangedCallback(VisiblePropertyChanged))
);
public IList VisibleItems {
get { return (IList)GetValue(VisibleItemsProperty); }
set { SetValue(VisibleItemsProperty, value); }
}
Run Code Online (Sandbox Code Playgroud)
通过单步进入VisiblePropertyChanged,我可以看到第一次设置CurrentTables时会触发它.但不是后来的时间.
UPDATE
有些人质疑CurrentTables的修改方式,它会在更改时完全重新分配:
OnDBChange()...
CurrentTables = new List<string>(MainDatabaseDataAdapter.GetTables(this.SelectedServer, this.SelectedDatabase));
Run Code Online (Sandbox Code Playgroud)
每次更改时都会调用此行,但我的VisiblePropertyChanged处理程序仅在第一次调用时才会被调用.
UPDATE
如果我直接分配VisibleItems,每次都会调用处理程序!
TestFilterList.VisibleItems = new List<string>( Enumerable.Range(1, DateTime.Now.Second).ToList().Select(s => s.ToString()).ToList() );
Run Code Online (Sandbox Code Playgroud)
因此,它看起来像这个问题从的DependencyProperty(VisibleItems)茎看其他的DependencyProperty(CurrentTables).不知何故,绑定适用于第一次属性更改,但不适用于后续属性?正如你们中的一些人所建议的,试图用snoop检查这个问题.
喜; 有源文件框和目标文本框txttarget有一个绑定到txtsource.当在txtsource中写一些东西时,txttarget就会改变.一切都很好.但是在txttarget上写道,我在txttarget上看不到任何变化?有TwoWay模式.Twoway模式还不够?我可以在不使用"UpdateSourceTrigger = PropertyChanged"的情况下编写吗?
<Grid>
<TextBox Height="23" HorizontalAlignment="Left" Margin="155,62,0,0" Name="txtSource" VerticalAlignment="Top" Width="120" />
<TextBox Height="23" HorizontalAlignment="Left"
Text="{Binding ElementName=txtSource,Path=Text,Mode=TwoWay}"
Margin="155,113,0,0" Name="txtTarget" VerticalAlignment="Top" Width="120" />
</Grid>
Run Code Online (Sandbox Code Playgroud) 我正在研究一个复杂的WPF应用程序,该应用程序几天就会挂起.除了GUI线程填充数据之外,还有一个线程可以将模型绑定到网格并触发INotifyPropertyChanged.PropertyChanged事件.我编写了一个脚本来将MDbg附加到挂起进程并转储线程的当前堆栈跟踪.在找到死锁原因时它会有很大帮助,但这次没有用.
正在更新模型的线程在获取时停止ReadLock:
Thread [#:8]
*0. WindowsBase.dll#0!MS.Internal.ReaderWriterLockWrapper.get_ReadLock() (source line information unavailable)
1. WindowsBase.dll#0!System.ComponentModel.PropertyChangedEventManager.OnPropertyChanged(sender=<...>, args=System.ComponentModel.PropertyChangedEventArgs) (source line information unavailable)
2. ( ... firing PropertyChanged event ... )
Run Code Online (Sandbox Code Playgroud)
GUI线程也发生了同样的事情:
Thread [#:0]
*0. WindowsBase.dll#0!MS.Internal.ReaderWriterLockWrapper.get_ReadLock() (source line information unavailable)
1. WindowsBase.dll#0!System.ComponentModel.PropertyChangedEventManager.OnPropertyChanged(sender=MyCompany.Windows.ViewModel.Window.WindowViewModel, args=System.ComponentModel.PropertyChangedEventArgs) (source line information unavailable)
2. MyCompany.Windows.Contracts.dll#0!MyCompany.Windows.ViewModel.Model.ViewModelItemBase.NotifyPropertyChanged(propertyName="IsActive") (source line information unavailable)
3. MyCompany.Windows.Contracts.dll#0!MyCompany.Windows.ViewModel.Window.WindowViewModel.set_IsActive(value=True) (source line information unavailable)
4. MyCompany.Windows.dll#0!MyCompany.Windows.ViewModel.Window.IsActiveBinding.OnWindowIsActiveChanged(sender=MyCompany.Xpf.Views.XpfRibbonShell.XpfRibbonShellView, e=System.EventArgs) (source line information unavailable)
5. WindowsBase.dll#0!MS.Internal.ComponentModel.PropertyChangeTracker.OnPropertyInvalidation(d=<N/A>, args=<N/A>) (source line information unavailable)
6. WindowsBase.dll#0!System.Windows.DependentList.InvalidateDependents(source=<N/A>, sourceArgs=<N/A>) (source line information unavailable)
7. WindowsBase.dll#0!System.Windows.DependencyObject.NotifyPropertyChange(args=<N/A>) …Run Code Online (Sandbox Code Playgroud) c# wpf multithreading propertychanged inotifypropertychanged
propertychanged ×10
c# ×8
wpf ×8
.net ×2
binding ×2
events ×1
multibinding ×1
properties ×1
static ×1
textbox ×1
xaml ×1