├── .gitattributes
├── .gitignore
├── README.md
├── RS.DouYinLearning.sln
├── RS.DouYinLearning
├── App.xaml
├── App.xaml.cs
├── AssemblyInfo.cs
├── Assets
│ ├── Galgg.jpg
│ ├── LzDic.jpg
│ ├── MeetingInDreamShouldLeadToAcquaintance.jpg
│ ├── clap.png
│ ├── iconfont.ttf
│ ├── lufeixue.jpg
│ ├── lynnf.jpg
│ ├── ocean.mp4
│ ├── ross.jpeg
│ ├── secretgift.png
│ ├── xiaohuzidashu.jpg
│ └── xiaoxianyu.jpg
├── BindingProxy.cs
├── MainWindow.xaml
├── MainWindow.xaml.cs
├── MainWindowViewModel.cs
├── Models
│ ├── AudienceModel.cs
│ ├── MsgModel.cs
│ ├── MsgType.cs
│ ├── RelationShip.cs
│ └── UserModel.cs
├── RS - Backup.DouYinLearning.csproj
└── RS.DouYinLearning.csproj
├── RS.DouYinUsercontrol
├── AssemblyInfo.cs
├── RS.DouYinUsercontrol.csproj
├── WinMonitorBtn.xaml
└── WinMonitorBtn.xaml.cs
├── RS.DouYinWidgets
├── AssemblyInfo.cs
├── Controls
│ ├── ControlsCommand.cs
│ ├── ControlsHelper.cs
│ ├── DragAdorner.cs
│ ├── RSDouYinWindow.cs
│ ├── RSDropDownBtn.cs
│ ├── RSPopBtn.cs
│ ├── RSSceneBtn.cs
│ └── TextBoxHelper.cs
├── Events
│ ├── IDrag.cs
│ └── RelayCommand.cs
├── Models
│ ├── ButtonModel.cs
│ └── NotifyBase.cs
├── RS.DouYinWidgets.csproj
├── Styles
│ ├── Controls.Boder.xaml
│ ├── Controls.Button.xaml
│ ├── Controls.CheckBox.xaml
│ ├── Controls.ControlTemplate.xaml
│ ├── Controls.Icons.xaml
│ ├── Controls.RadioButton.xaml
│ ├── Controls.ScrollBar.xaml
│ ├── Controls.ScrollViewer.xaml
│ ├── Controls.Slider.xaml
│ ├── Controls.TextBox.xaml
│ ├── Controls.Thumb.xaml
│ ├── Controls.Tooltip.xaml
│ └── Controls.xaml
└── Themes
│ ├── Generic.xaml
│ ├── RSDouYinWindow.xaml
│ ├── RSDropDownBtn.xaml
│ ├── RSPopBtn.xaml
│ └── RSSceneBtn.xaml
└── TEST
├── AssemblyInfo.cs
├── Controls
├── RSDouYinWindow.cs
└── Rsdfsjfdlsjflsjflksjflksjfljslfjslkfsdf.cs
├── TEST.csproj
└── Themes
├── Generic.xaml
└── RSDouYinWindow.xaml
/.gitattributes:
--------------------------------------------------------------------------------
1 | ###############################################################################
2 | # Set default behavior to automatically normalize line endings.
3 | ###############################################################################
4 | * text=auto
5 |
6 | ###############################################################################
7 | # Set default behavior for command prompt diff.
8 | #
9 | # This is need for earlier builds of msysgit that does not have it on by
10 | # default for csharp files.
11 | # Note: This is only used by command line
12 | ###############################################################################
13 | #*.cs diff=csharp
14 |
15 | ###############################################################################
16 | # Set the merge driver for project and solution files
17 | #
18 | # Merging from the command prompt will add diff markers to the files if there
19 | # are conflicts (Merging from VS is not affected by the settings below, in VS
20 | # the diff markers are never inserted). Diff markers may cause the following
21 | # file extensions to fail to load in VS. An alternative would be to treat
22 | # these files as binary and thus will always conflict and require user
23 | # intervention with every merge. To do so, just uncomment the entries below
24 | ###############################################################################
25 | #*.sln merge=binary
26 | #*.csproj merge=binary
27 | #*.vbproj merge=binary
28 | #*.vcxproj merge=binary
29 | #*.vcproj merge=binary
30 | #*.dbproj merge=binary
31 | #*.fsproj merge=binary
32 | #*.lsproj merge=binary
33 | #*.wixproj merge=binary
34 | #*.modelproj merge=binary
35 | #*.sqlproj merge=binary
36 | #*.wwaproj merge=binary
37 |
38 | ###############################################################################
39 | # behavior for image files
40 | #
41 | # image files are treated as binary by default.
42 | ###############################################################################
43 | #*.jpg binary
44 | #*.png binary
45 | #*.gif binary
46 |
47 | ###############################################################################
48 | # diff behavior for common document formats
49 | #
50 | # Convert binary document formats to text before diffing them. This feature
51 | # is only available from the command line. Turn it on by uncommenting the
52 | # entries below.
53 | ###############################################################################
54 | #*.doc diff=astextplain
55 | #*.DOC diff=astextplain
56 | #*.docx diff=astextplain
57 | #*.DOCX diff=astextplain
58 | #*.dot diff=astextplain
59 | #*.DOT diff=astextplain
60 | #*.pdf diff=astextplain
61 | #*.PDF diff=astextplain
62 | #*.rtf diff=astextplain
63 | #*.RTF diff=astextplain
64 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | ## Ignore Visual Studio temporary files, build results, and
2 | ## files generated by popular Visual Studio add-ons.
3 | ##
4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
5 |
6 | # User-specific files
7 | *.rsuser
8 | *.suo
9 | *.user
10 | *.userosscache
11 | *.sln.docstates
12 |
13 | # User-specific files (MonoDevelop/Xamarin Studio)
14 | *.userprefs
15 |
16 | # Mono auto generated files
17 | mono_crash.*
18 |
19 | # Build results
20 | [Dd]ebug/
21 | [Dd]ebugPublic/
22 | [Rr]elease/
23 | [Rr]eleases/
24 | x64/
25 | x86/
26 | [Ww][Ii][Nn]32/
27 | [Aa][Rr][Mm]/
28 | [Aa][Rr][Mm]64/
29 | bld/
30 | [Bb]in/
31 | [Oo]bj/
32 | [Oo]ut/
33 | [Ll]og/
34 | [Ll]ogs/
35 |
36 | # Visual Studio 2015/2017 cache/options directory
37 | .vs/
38 | # Uncomment if you have tasks that create the project's static files in wwwroot
39 | #wwwroot/
40 |
41 | # Visual Studio 2017 auto generated files
42 | Generated\ Files/
43 |
44 | # MSTest test Results
45 | [Tt]est[Rr]esult*/
46 | [Bb]uild[Ll]og.*
47 |
48 | # NUnit
49 | *.VisualState.xml
50 | TestResult.xml
51 | nunit-*.xml
52 |
53 | # Build Results of an ATL Project
54 | [Dd]ebugPS/
55 | [Rr]eleasePS/
56 | dlldata.c
57 |
58 | # Benchmark Results
59 | BenchmarkDotNet.Artifacts/
60 |
61 | # .NET Core
62 | project.lock.json
63 | project.fragment.lock.json
64 | artifacts/
65 |
66 | # ASP.NET Scaffolding
67 | ScaffoldingReadMe.txt
68 |
69 | # StyleCop
70 | StyleCopReport.xml
71 |
72 | # Files built by Visual Studio
73 | *_i.c
74 | *_p.c
75 | *_h.h
76 | *.ilk
77 | *.meta
78 | *.obj
79 | *.iobj
80 | *.pch
81 | *.pdb
82 | *.ipdb
83 | *.pgc
84 | *.pgd
85 | *.rsp
86 | *.sbr
87 | *.tlb
88 | *.tli
89 | *.tlh
90 | *.tmp
91 | *.tmp_proj
92 | *_wpftmp.csproj
93 | *.log
94 | *.vspscc
95 | *.vssscc
96 | .builds
97 | *.pidb
98 | *.svclog
99 | *.scc
100 |
101 | # Chutzpah Test files
102 | _Chutzpah*
103 |
104 | # Visual C++ cache files
105 | ipch/
106 | *.aps
107 | *.ncb
108 | *.opendb
109 | *.opensdf
110 | *.sdf
111 | *.cachefile
112 | *.VC.db
113 | *.VC.VC.opendb
114 |
115 | # Visual Studio profiler
116 | *.psess
117 | *.vsp
118 | *.vspx
119 | *.sap
120 |
121 | # Visual Studio Trace Files
122 | *.e2e
123 |
124 | # TFS 2012 Local Workspace
125 | $tf/
126 |
127 | # Guidance Automation Toolkit
128 | *.gpState
129 |
130 | # ReSharper is a .NET coding add-in
131 | _ReSharper*/
132 | *.[Rr]e[Ss]harper
133 | *.DotSettings.user
134 |
135 | # TeamCity is a build add-in
136 | _TeamCity*
137 |
138 | # DotCover is a Code Coverage Tool
139 | *.dotCover
140 |
141 | # AxoCover is a Code Coverage Tool
142 | .axoCover/*
143 | !.axoCover/settings.json
144 |
145 | # Coverlet is a free, cross platform Code Coverage Tool
146 | coverage*.json
147 | coverage*.xml
148 | coverage*.info
149 |
150 | # Visual Studio code coverage results
151 | *.coverage
152 | *.coveragexml
153 |
154 | # NCrunch
155 | _NCrunch_*
156 | .*crunch*.local.xml
157 | nCrunchTemp_*
158 |
159 | # MightyMoose
160 | *.mm.*
161 | AutoTest.Net/
162 |
163 | # Web workbench (sass)
164 | .sass-cache/
165 |
166 | # Installshield output folder
167 | [Ee]xpress/
168 |
169 | # DocProject is a documentation generator add-in
170 | DocProject/buildhelp/
171 | DocProject/Help/*.HxT
172 | DocProject/Help/*.HxC
173 | DocProject/Help/*.hhc
174 | DocProject/Help/*.hhk
175 | DocProject/Help/*.hhp
176 | DocProject/Help/Html2
177 | DocProject/Help/html
178 |
179 | # Click-Once directory
180 | publish/
181 |
182 | # Publish Web Output
183 | *.[Pp]ublish.xml
184 | *.azurePubxml
185 | # Note: Comment the next line if you want to checkin your web deploy settings,
186 | # but database connection strings (with potential passwords) will be unencrypted
187 | *.pubxml
188 | *.publishproj
189 |
190 | # Microsoft Azure Web App publish settings. Comment the next line if you want to
191 | # checkin your Azure Web App publish settings, but sensitive information contained
192 | # in these scripts will be unencrypted
193 | PublishScripts/
194 |
195 | # NuGet Packages
196 | *.nupkg
197 | # NuGet Symbol Packages
198 | *.snupkg
199 | # The packages folder can be ignored because of Package Restore
200 | **/[Pp]ackages/*
201 | # except build/, which is used as an MSBuild target.
202 | !**/[Pp]ackages/build/
203 | # Uncomment if necessary however generally it will be regenerated when needed
204 | #!**/[Pp]ackages/repositories.config
205 | # NuGet v3's project.json files produces more ignorable files
206 | *.nuget.props
207 | *.nuget.targets
208 |
209 | # Microsoft Azure Build Output
210 | csx/
211 | *.build.csdef
212 |
213 | # Microsoft Azure Emulator
214 | ecf/
215 | rcf/
216 |
217 | # Windows Store app package directories and files
218 | AppPackages/
219 | BundleArtifacts/
220 | Package.StoreAssociation.xml
221 | _pkginfo.txt
222 | *.appx
223 | *.appxbundle
224 | *.appxupload
225 |
226 | # Visual Studio cache files
227 | # files ending in .cache can be ignored
228 | *.[Cc]ache
229 | # but keep track of directories ending in .cache
230 | !?*.[Cc]ache/
231 |
232 | # Others
233 | ClientBin/
234 | ~$*
235 | *~
236 | *.dbmdl
237 | *.dbproj.schemaview
238 | *.jfm
239 | *.pfx
240 | *.publishsettings
241 | orleans.codegen.cs
242 |
243 | # Including strong name files can present a security risk
244 | # (https://github.com/github/gitignore/pull/2483#issue-259490424)
245 | #*.snk
246 |
247 | # Since there are multiple workflows, uncomment next line to ignore bower_components
248 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
249 | #bower_components/
250 |
251 | # RIA/Silverlight projects
252 | Generated_Code/
253 |
254 | # Backup & report files from converting an old project file
255 | # to a newer Visual Studio version. Backup files are not needed,
256 | # because we have git ;-)
257 | _UpgradeReport_Files/
258 | Backup*/
259 | UpgradeLog*.XML
260 | UpgradeLog*.htm
261 | ServiceFabricBackup/
262 | *.rptproj.bak
263 |
264 | # SQL Server files
265 | *.mdf
266 | *.ldf
267 | *.ndf
268 |
269 | # Business Intelligence projects
270 | *.rdl.data
271 | *.bim.layout
272 | *.bim_*.settings
273 | *.rptproj.rsuser
274 | *- [Bb]ackup.rdl
275 | *- [Bb]ackup ([0-9]).rdl
276 | *- [Bb]ackup ([0-9][0-9]).rdl
277 |
278 | # Microsoft Fakes
279 | FakesAssemblies/
280 |
281 | # GhostDoc plugin setting file
282 | *.GhostDoc.xml
283 |
284 | # Node.js Tools for Visual Studio
285 | .ntvs_analysis.dat
286 | node_modules/
287 |
288 | # Visual Studio 6 build log
289 | *.plg
290 |
291 | # Visual Studio 6 workspace options file
292 | *.opt
293 |
294 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
295 | *.vbw
296 |
297 | # Visual Studio LightSwitch build output
298 | **/*.HTMLClient/GeneratedArtifacts
299 | **/*.DesktopClient/GeneratedArtifacts
300 | **/*.DesktopClient/ModelManifest.xml
301 | **/*.Server/GeneratedArtifacts
302 | **/*.Server/ModelManifest.xml
303 | _Pvt_Extensions
304 |
305 | # Paket dependency manager
306 | .paket/paket.exe
307 | paket-files/
308 |
309 | # FAKE - F# Make
310 | .fake/
311 |
312 | # CodeRush personal settings
313 | .cr/personal
314 |
315 | # Python Tools for Visual Studio (PTVS)
316 | __pycache__/
317 | *.pyc
318 |
319 | # Cake - Uncomment if you are using it
320 | # tools/**
321 | # !tools/packages.config
322 |
323 | # Tabs Studio
324 | *.tss
325 |
326 | # Telerik's JustMock configuration file
327 | *.jmconfig
328 |
329 | # BizTalk build output
330 | *.btp.cs
331 | *.btm.cs
332 | *.odx.cs
333 | *.xsd.cs
334 |
335 | # OpenCover UI analysis results
336 | OpenCover/
337 |
338 | # Azure Stream Analytics local run output
339 | ASALocalRun/
340 |
341 | # MSBuild Binary and Structured Log
342 | *.binlog
343 |
344 | # NVidia Nsight GPU debugger configuration file
345 | *.nvuser
346 |
347 | # MFractors (Xamarin productivity tool) working folder
348 | .mfractor/
349 |
350 | # Local History for Visual Studio
351 | .localhistory/
352 |
353 | # BeatPulse healthcheck temp database
354 | healthchecksdb
355 |
356 | # Backup folder for Package Reference Convert tool in Visual Studio 2017
357 | MigrationBackup/
358 |
359 | # Ionide (cross platform F# VS Code tools) working folder
360 | .ionide/
361 |
362 | # Fody - auto-generated XML schema
363 | FodyWeavers.xsd
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | Please note that this project is only used for personal research and learning.
2 | Learn how to use the WPF MVVM framework to develop and create your own custom controls according to Tiktok live broadcast partners.
3 | Please do not use it for commercial purposes. Otherwise, the consequences will be borne by oneself!!!!
4 |
5 | 请注意,这个项目仅作为个人研究学习使用,根据抖音直播伴侣去学习如何使用WPF MVVM框架开发创建自己的自定义控件,请不要用于商业目的。否则后果自负!!!!
6 |
7 | 如有任何侵权行为,请直接联系我,第一时间移除该Repository.
8 |
9 | 下面是效果图。
10 |
11 | 
12 |
13 |
14 | 特别鸣谢
15 | 抖音直播伴侣 https://streamingtool.douyin.com/
16 |
17 | 
18 |
19 | 阿里巴巴矢量图标库 https://www.iconfont.cn/
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/RS.DouYinLearning.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 17
4 | VisualStudioVersion = 17.11.35312.102
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RS.DouYinLearning", "RS.DouYinLearning\RS.DouYinLearning.csproj", "{ADBBAEEA-94EF-4047-BE42-4CA1A6697523}"
7 | EndProject
8 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RS.DouYinWidgets", "RS.DouYinWidgets\RS.DouYinWidgets.csproj", "{CB015935-AD04-458D-8DA2-BD5AC1C4882F}"
9 | EndProject
10 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RS.DouYinUsercontrol", "RS.DouYinUsercontrol\RS.DouYinUsercontrol.csproj", "{A0EC5F87-0042-4518-BDAC-76D36EE4808A}"
11 | EndProject
12 | Global
13 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
14 | Debug|Any CPU = Debug|Any CPU
15 | Release|Any CPU = Release|Any CPU
16 | EndGlobalSection
17 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
18 | {ADBBAEEA-94EF-4047-BE42-4CA1A6697523}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
19 | {ADBBAEEA-94EF-4047-BE42-4CA1A6697523}.Debug|Any CPU.Build.0 = Debug|Any CPU
20 | {ADBBAEEA-94EF-4047-BE42-4CA1A6697523}.Release|Any CPU.ActiveCfg = Release|Any CPU
21 | {ADBBAEEA-94EF-4047-BE42-4CA1A6697523}.Release|Any CPU.Build.0 = Release|Any CPU
22 | {CB015935-AD04-458D-8DA2-BD5AC1C4882F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
23 | {CB015935-AD04-458D-8DA2-BD5AC1C4882F}.Debug|Any CPU.Build.0 = Debug|Any CPU
24 | {CB015935-AD04-458D-8DA2-BD5AC1C4882F}.Release|Any CPU.ActiveCfg = Release|Any CPU
25 | {CB015935-AD04-458D-8DA2-BD5AC1C4882F}.Release|Any CPU.Build.0 = Release|Any CPU
26 | {A0EC5F87-0042-4518-BDAC-76D36EE4808A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
27 | {A0EC5F87-0042-4518-BDAC-76D36EE4808A}.Debug|Any CPU.Build.0 = Debug|Any CPU
28 | {A0EC5F87-0042-4518-BDAC-76D36EE4808A}.Release|Any CPU.ActiveCfg = Release|Any CPU
29 | {A0EC5F87-0042-4518-BDAC-76D36EE4808A}.Release|Any CPU.Build.0 = Release|Any CPU
30 | EndGlobalSection
31 | GlobalSection(SolutionProperties) = preSolution
32 | HideSolutionNode = FALSE
33 | EndGlobalSection
34 | GlobalSection(ExtensibilityGlobals) = postSolution
35 | SolutionGuid = {38404991-A716-47D5-BDD6-01F780B30615}
36 | EndGlobalSection
37 | EndGlobal
38 |
--------------------------------------------------------------------------------
/RS.DouYinLearning/App.xaml:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
16 | pack://application:,,,/RS.DouYinLearning;component/Assets/#iconfont
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/RS.DouYinLearning/App.xaml.cs:
--------------------------------------------------------------------------------
1 | using System.Configuration;
2 | using System.Data;
3 | using System.Windows;
4 |
5 | namespace RS.DouYinLearning
6 | {
7 | ///
8 | /// Interaction logic for App.xaml
9 | ///
10 | public partial class App : Application
11 | {
12 | }
13 |
14 | }
15 |
--------------------------------------------------------------------------------
/RS.DouYinLearning/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Windows;
2 |
3 | [assembly: ThemeInfo(
4 | ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
5 | //(used if a resource is not found in the page,
6 | // or application resource dictionaries)
7 | ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
8 | //(used if a resource is not found in the page,
9 | // app, or any theme specific resource dictionaries)
10 | )]
11 |
--------------------------------------------------------------------------------
/RS.DouYinLearning/Assets/Galgg.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/luo-ross/douyinwpfdemo/a5cb7b5971de738cfe4f037223595e3df968ce30/RS.DouYinLearning/Assets/Galgg.jpg
--------------------------------------------------------------------------------
/RS.DouYinLearning/Assets/LzDic.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/luo-ross/douyinwpfdemo/a5cb7b5971de738cfe4f037223595e3df968ce30/RS.DouYinLearning/Assets/LzDic.jpg
--------------------------------------------------------------------------------
/RS.DouYinLearning/Assets/MeetingInDreamShouldLeadToAcquaintance.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/luo-ross/douyinwpfdemo/a5cb7b5971de738cfe4f037223595e3df968ce30/RS.DouYinLearning/Assets/MeetingInDreamShouldLeadToAcquaintance.jpg
--------------------------------------------------------------------------------
/RS.DouYinLearning/Assets/clap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/luo-ross/douyinwpfdemo/a5cb7b5971de738cfe4f037223595e3df968ce30/RS.DouYinLearning/Assets/clap.png
--------------------------------------------------------------------------------
/RS.DouYinLearning/Assets/iconfont.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/luo-ross/douyinwpfdemo/a5cb7b5971de738cfe4f037223595e3df968ce30/RS.DouYinLearning/Assets/iconfont.ttf
--------------------------------------------------------------------------------
/RS.DouYinLearning/Assets/lufeixue.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/luo-ross/douyinwpfdemo/a5cb7b5971de738cfe4f037223595e3df968ce30/RS.DouYinLearning/Assets/lufeixue.jpg
--------------------------------------------------------------------------------
/RS.DouYinLearning/Assets/lynnf.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/luo-ross/douyinwpfdemo/a5cb7b5971de738cfe4f037223595e3df968ce30/RS.DouYinLearning/Assets/lynnf.jpg
--------------------------------------------------------------------------------
/RS.DouYinLearning/Assets/ocean.mp4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/luo-ross/douyinwpfdemo/a5cb7b5971de738cfe4f037223595e3df968ce30/RS.DouYinLearning/Assets/ocean.mp4
--------------------------------------------------------------------------------
/RS.DouYinLearning/Assets/ross.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/luo-ross/douyinwpfdemo/a5cb7b5971de738cfe4f037223595e3df968ce30/RS.DouYinLearning/Assets/ross.jpeg
--------------------------------------------------------------------------------
/RS.DouYinLearning/Assets/secretgift.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/luo-ross/douyinwpfdemo/a5cb7b5971de738cfe4f037223595e3df968ce30/RS.DouYinLearning/Assets/secretgift.png
--------------------------------------------------------------------------------
/RS.DouYinLearning/Assets/xiaohuzidashu.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/luo-ross/douyinwpfdemo/a5cb7b5971de738cfe4f037223595e3df968ce30/RS.DouYinLearning/Assets/xiaohuzidashu.jpg
--------------------------------------------------------------------------------
/RS.DouYinLearning/Assets/xiaoxianyu.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/luo-ross/douyinwpfdemo/a5cb7b5971de738cfe4f037223595e3df968ce30/RS.DouYinLearning/Assets/xiaoxianyu.jpg
--------------------------------------------------------------------------------
/RS.DouYinLearning/BindingProxy.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.ComponentModel;
4 | using System.Linq;
5 | using System.Text;
6 | using System.Threading.Tasks;
7 | using System.Windows;
8 |
9 | namespace RS.DouYinLearning
10 | {
11 | public class BindingProxy : Freezable
12 | {
13 |
14 | public object Data
15 | {
16 | get { return (object)GetValue(DataProperty); }
17 | set { SetValue(DataProperty, value); }
18 | }
19 |
20 | public static readonly DependencyProperty DataProperty =
21 | DependencyProperty.Register("Data", typeof(object), typeof(BindingProxy));
22 |
23 |
24 | protected override Freezable CreateInstanceCore()
25 | {
26 | return new BindingProxy();
27 | }
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/RS.DouYinLearning/MainWindow.xaml.cs:
--------------------------------------------------------------------------------
1 | using RS.DouYinWidgets.Controls;
2 | using RS.DouYinWidgets.Events;
3 | using System.ComponentModel;
4 | using System.Diagnostics;
5 | using System.Reflection;
6 | using System.Text;
7 | using System.Windows;
8 | using System.Windows.Controls;
9 | using System.Windows.Controls.Primitives;
10 | using System.Windows.Data;
11 | using System.Windows.Documents;
12 | using System.Windows.Input;
13 | using System.Windows.Media;
14 | using System.Windows.Media.Animation;
15 | using System.Windows.Media.Imaging;
16 | using System.Windows.Navigation;
17 | using System.Windows.Shapes;
18 | using System.Xml;
19 | using System.Xml.Linq;
20 |
21 | namespace RS.DouYinLearning
22 | {
23 | ///
24 | /// Interaction logic for MainWindow.xaml
25 | ///
26 | public partial class MainWindow : RSDouYinWindow
27 | {
28 | public MainWindowViewModel ViewModel { get; set; }
29 |
30 | public MainWindow()
31 | {
32 | InitializeComponent();
33 | this.ViewModel = this.DataContext as MainWindowViewModel;
34 | this.Loaded += MainWindow_Loaded;
35 | }
36 |
37 | private void MainWindow_Loaded(object sender, RoutedEventArgs e)
38 | {
39 | Task.Factory.StartNew(async () =>
40 | {
41 | while (true)
42 | {
43 | //await Task.Delay(500);
44 | //this.Dispatcher.Invoke(() =>
45 | //{
46 | // BtnMonitor1.Foreground = new SolidColorBrush(Colors.Red);
47 | //});
48 | //await Task.Delay(500);
49 | //this.Dispatcher.Invoke(() =>
50 | //{
51 | // BtnMonitor1.Foreground = new SolidColorBrush(Colors.Green);
52 | //});
53 | this.ViewModel.VolumeLevel = new Random(Guid.NewGuid().GetHashCode()).NextDouble();
54 | await Task.Delay(80);
55 | }
56 | });
57 | }
58 |
59 | private void BtnMonitor1_OnCkEyeShowHide(DouYinUsercontrol.WinMonitorBtn arg1, bool arg2)
60 | {
61 | }
62 |
63 | private void BtnMonitor1_LockMaterialsClick(object sender, RoutedEventArgs e)
64 | {
65 | }
66 |
67 | private void PART_Canvas_MouseMove(object sender, MouseEventArgs e)
68 | {
69 |
70 | }
71 |
72 |
73 | private void GetVisualChildrenRecursive(DependencyObject parent, List children)
74 | {
75 | int count = VisualTreeHelper.GetChildrenCount(parent);
76 | for (int i = 0; i < count; i++)
77 | {
78 | DependencyObject child = VisualTreeHelper.GetChild(parent, i);
79 | children.Add(child);
80 | // 继续递归子控件的子控件
81 | GetVisualChildrenRecursive(child, children);
82 | }
83 | }
84 |
85 |
86 |
87 |
88 | private void RSDouYinWindow_MouseMove(object sender, MouseEventArgs e)
89 | {
90 | var position = e.GetPosition(this.CanvasHost);
91 | Canvas.SetLeft(this.DragContent, position.X - this.DragContent.ActualWidth / 2);
92 | Canvas.SetTop(this.DragContent, position.Y - this.DragContent.ActualHeight / 2);
93 | e.Handled = true;
94 | }
95 |
96 |
97 | public FrameworkElement DragTarget { get; set; }
98 | public Panel DragTargetHost { get; set; }
99 |
100 | private void RSDouYinWindow_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
101 | {
102 | var mouseDownPostion = e.GetPosition(this.BorderHost);
103 | var element = this.GetIDragUnderMouse(this.BorderHost, mouseDownPostion);
104 | if (element == null)
105 | {
106 | return;
107 | }
108 | DragTargetHost = (Panel)VisualTreeHelper.GetParent((FrameworkElement)element);
109 | DragTarget = (FrameworkElement)element;
110 | if (DragTarget != null)
111 | {
112 | var actualWidth = DragTarget.ActualWidth;
113 | var actualHeight = DragTarget.ActualHeight;
114 |
115 |
116 | //var adornerLayer = AdornerLayer.GetAdornerLayer(DragTarget);
117 | //adornerLayer.Add(new DragAdorner(DragTarget, actualWidth, actualHeight));
118 |
119 | var bitmap = ConvertToBitmapSource(DragTarget);
120 | this.DragContent.Visibility = Visibility.Visible;
121 | this.DragContent.Width = actualWidth;
122 | this.DragContent.Height = actualHeight;
123 | this.DragContent.Background = new VisualBrush(DragTarget);
124 | //this.DragContent.Background = new ImageBrush(bitmap);
125 | var canvasHostPoint = e.GetPosition(this.CanvasHost);
126 | Canvas.SetLeft(this.DragContent, canvasHostPoint.X - actualWidth / 2);
127 | Canvas.SetTop(this.DragContent, canvasHostPoint.Y - actualHeight / 2);
128 | //DragTarget.Visibility = Visibility.Collapsed;
129 | //this.CaptureMouse();
130 | e.Handled = true;
131 | }
132 | }
133 |
134 | private IDrag GetIDragUnderMouse(UIElement uIElement, Point mousePosition)
135 | {
136 | var hitTestResult = VisualTreeHelper.HitTest(uIElement, mousePosition);
137 | var visualHit = hitTestResult?.VisualHit;
138 |
139 | while (visualHit != null)
140 | {
141 | var child = visualHit as IDrag;
142 | if (child != null)
143 | {
144 | return child;
145 | }
146 | visualHit = VisualTreeHelper.GetParent(visualHit);
147 | }
148 | return null;
149 | }
150 |
151 | private T GetElementUnderMouse(UIElement uIElement, Point mousePosition) where T : UIElement
152 | {
153 | var hitTestResult = VisualTreeHelper.HitTest(uIElement, mousePosition);
154 | var visualHit = hitTestResult?.VisualHit;
155 |
156 | while (visualHit != null)
157 | {
158 | var child = visualHit as T;
159 | if (child != null)
160 | {
161 | return child;
162 | }
163 | visualHit = VisualTreeHelper.GetParent(visualHit);
164 | }
165 | return null;
166 | }
167 |
168 | public static BitmapSource ConvertToBitmapSource(UIElement element)
169 | {
170 | // 创建一个用于渲染的可视化对象容器
171 | var visual = new DrawingVisual();
172 | using (var context = visual.RenderOpen())
173 | {
174 | // 将传入的UI元素(这里是Button等控件)添加到渲染上下文中
175 | var brush = new VisualBrush(element);
176 | context.DrawRectangle(brush, null, new Rect(new Point(0, 0), new Point(element.RenderSize.Width, element.RenderSize.Height)));
177 | }
178 | // 创建一个渲染目标位图
179 | var bitmap = new RenderTargetBitmap((int)element.RenderSize.Width, (int)element.RenderSize.Height, 96, 96, PixelFormats.Pbgra32);
180 | // 将可视化对象渲染到位图上
181 | bitmap.Render(visual);
182 | return bitmap;
183 | }
184 |
185 |
186 | private void RSDouYinWindow_PreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
187 | {
188 | if (this.DragTarget == null)
189 | {
190 | return;
191 | }
192 | var mouseDownPostion = e.GetPosition(this.BorderHost);
193 | var gridHost = this.GetElementUnderMouse(this.BorderHost, mouseDownPostion);
194 | if (gridHost != null)
195 | {
196 | if (gridHost is Panel panel)
197 | {
198 | if (!panel.Children.Contains(DragTarget))
199 | {
200 | DragTargetHost.Children.Remove(DragTarget);
201 | panel.Children.Add(DragTarget);
202 | DragTarget.Visibility = Visibility.Visible;
203 | this.DragContent.Visibility = Visibility.Collapsed;
204 | return;
205 | }
206 |
207 | }
208 | }
209 | DragTarget.Visibility = Visibility.Visible;
210 | this.DragContent.Visibility = Visibility.Collapsed;
211 | }
212 |
213 | private void Button_Click(object sender, RoutedEventArgs e)
214 | {
215 | //this.PopularityChartTest.Storyboard.Stop();
216 | //this.HourChartTest.Storyboard.Stop();
217 | //this.ViewModel.BeginThickness = new Thickness(10, 0, 5, -50);
218 | //this.ViewModel.EndThickness = new Thickness(10, 0, 5, 50);
219 | //this.PopularityChartTest.Storyboard.Begin();
220 | //this.HourChartTest.Storyboard.Begin();
221 | }
222 |
223 | private void MediaVideo_MediaEnded(object sender, RoutedEventArgs e)
224 | {
225 | this.MediaVideo.Position = new TimeSpan(0);
226 | this.MediaVideo.Play();
227 | }
228 |
229 | private void MediaVideo_Loaded(object sender, RoutedEventArgs e)
230 | {
231 | this.MediaVideo.Position = new TimeSpan(0);
232 | this.MediaVideo.Play();
233 | }
234 |
235 | private void BtnSendMsg_Click(object sender, RoutedEventArgs e)
236 | {
237 | this.SendMsg();
238 | }
239 |
240 | private void SendMsg()
241 | {
242 | this.ViewModel.SendMsg(this.TxtSendMessage);
243 | this.MsgScrollViewer.ScrollToBottom();
244 | }
245 |
246 | private void BtnSendMsg_PreviewKeyDown(object sender, KeyEventArgs e)
247 | {
248 | this.SendMsg();
249 | }
250 | }
251 | }
--------------------------------------------------------------------------------
/RS.DouYinLearning/MainWindowViewModel.cs:
--------------------------------------------------------------------------------
1 | using RS.DouYinWidgets.Models;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Collections.ObjectModel;
5 | using System.Linq;
6 | using System.Reflection.Metadata;
7 | using System.Text;
8 | using System.Threading.Tasks;
9 | using System.Windows.Controls;
10 | using System.Windows;
11 | using System.Windows.Input;
12 | using RS.DouYinLearning.Models;
13 | using RS.DouYinWidgets.Events;
14 | using System.Windows.Interop;
15 |
16 | namespace RS.DouYinLearning
17 | {
18 | public class MainWindowViewModel : NotifyBase
19 | {
20 |
21 | public MainWindowViewModel()
22 | {
23 | this.SendMsgCommand = new RelayCommand(SendMsg, CanSendMsg);
24 | }
25 |
26 | private bool CanSendMsg(object arg)
27 | {
28 | return true;
29 | }
30 |
31 | public void SendMsg(object obj)
32 | {
33 | var textBox = obj as TextBox;
34 | string msgSend = textBox.Text;
35 | if (string.IsNullOrEmpty(msgSend)||string.IsNullOrWhiteSpace(msgSend))
36 | {
37 | textBox.Text = "";
38 | textBox.Focus();
39 | return;
40 | }
41 |
42 |
43 | this.MsgModelPageList.Add(new MsgModel()
44 | {
45 | Degree = 70,
46 | IsFansTeam = true,
47 | MsgInfo = textBox.Text,
48 | MsgType = MsgType.NormalMsg,
49 | NickName = "行云游者"
50 | });
51 | textBox.Text = "";
52 | textBox.Focus();
53 | }
54 |
55 |
56 |
57 | private ICommand sendMsgCommand;
58 | ///
59 | /// 发送消息
60 | ///
61 |
62 | public ICommand SendMsgCommand
63 | {
64 | get
65 | {
66 | return sendMsgCommand;
67 | }
68 | set
69 | {
70 | sendMsgCommand = value;
71 | this.OnPropertyChanged();
72 | }
73 | }
74 |
75 |
76 |
77 |
78 | private ObservableCollection buttonModelList;
79 | ///
80 | /// 模式命令列表
81 | ///
82 |
83 | public ObservableCollection ButtonModelList
84 | {
85 | get
86 | {
87 | if (buttonModelList == null)
88 | {
89 | buttonModelList = new ObservableCollection();
90 | buttonModelList.Add(new ButtonModel() { BtnDes = "常规模式", BtnCommand = null });
91 | buttonModelList.Add(new ButtonModel() { BtnDes = "语音模式", BtnCommand = null });
92 | buttonModelList.Add(new ButtonModel() { BtnDes = "嘉宾模式", BtnCommand = null });
93 | buttonModelList.Add(new ButtonModel() { BtnDes = "助播模式", BtnCommand = null });
94 | }
95 | return buttonModelList;
96 | }
97 | set
98 | {
99 | buttonModelList = value;
100 | this.OnPropertyChanged();
101 | }
102 | }
103 |
104 | private Thickness beginThickness = new Thickness(10, 0, 5, -50);
105 | ///
106 | /// 默认Thickness
107 | ///
108 |
109 | public Thickness BeginThickness
110 | {
111 | get
112 | {
113 | return beginThickness;
114 | }
115 | set
116 | {
117 | beginThickness = value;
118 | this.OnPropertyChanged();
119 | }
120 | }
121 |
122 |
123 | private Thickness endThickness = new Thickness(10, 0, 5, 0);
124 | ///
125 | /// 默认Thickness
126 | ///
127 |
128 | public Thickness EndThickness
129 | {
130 | get
131 | {
132 | return endThickness;
133 | }
134 | set
135 | {
136 | endThickness = value;
137 | this.OnPropertyChanged();
138 | }
139 | }
140 |
141 | private double volumeLevel;
142 | ///
143 | /// 声音大小
144 | ///
145 |
146 | public double VolumeLevel
147 | {
148 | get
149 | {
150 | return volumeLevel;
151 | }
152 | set
153 | {
154 | volumeLevel = value;
155 | this.OnPropertyChanged();
156 | }
157 | }
158 |
159 |
160 | private ObservableCollection audienceModelList;
161 | ///
162 | /// 观众列表
163 | ///
164 |
165 | public ObservableCollection AudienceModelList
166 | {
167 | get
168 | {
169 |
170 |
171 | if (audienceModelList == null)
172 | {
173 | audienceModelList = new ObservableCollection();
174 | audienceModelList.Add(new AudienceModel()
175 | {
176 | Number = 1,
177 | Contribution = 11,
178 | Degree = 10,
179 | ImgLink = "Assets/xiaohuzidashu.jpg",
180 | NickName = "小胡子大叔608",
181 | RelationShip = RelationShip.Fans,
182 | Location = "浙江",
183 | InterestCount = 10,
184 | FansCount = 20,
185 |
186 | CommentCount = 10,
187 | GiftCollectionCount = 4,
188 | GiftCount = 5,
189 | InteractionBegin = DateTime.Now.AddDays(-7),
190 | InteractionEnd = DateTime.Now,
191 | IsFansTeam = true,
192 | IsGiftCollection = true,
193 | Last7DaysComments = 7,
194 | Last7DaysGift = 2,
195 | Last7DaysView = 7,
196 | ViewDay = 5,
197 | ViewTime = 40
198 | });
199 |
200 | audienceModelList.Add(new AudienceModel()
201 | {
202 | Number = 2,
203 | Contribution = 11,
204 | Degree = 10,
205 | ImgLink = "Assets/MeetingInDreamShouldLeadToAcquaintance.jpg",
206 | NickName = "梦里相遇应相识",
207 | RelationShip = RelationShip.Friend,
208 | Location = "北京",
209 | InterestCount = 10,
210 | FansCount = 20,
211 |
212 |
213 | CommentCount = 10,
214 | GiftCollectionCount = 4,
215 | GiftCount = 5,
216 | InteractionBegin = DateTime.Now.AddDays(-7),
217 | InteractionEnd = DateTime.Now,
218 | IsFansTeam = true,
219 | IsGiftCollection = true,
220 | Last7DaysComments = 7,
221 | Last7DaysGift = 2,
222 | Last7DaysView = 7,
223 | ViewDay = 5,
224 | ViewTime = 40
225 | });
226 | audienceModelList.Add(new AudienceModel()
227 | {
228 | Number = 3,
229 | Contribution = 11,
230 | Degree = 0,
231 | ImgLink = "Assets/LzDic.jpg",
232 | NickName = "LzDic",
233 | RelationShip = RelationShip.Fans,
234 | Location = "上海",
235 | InterestCount = 100,
236 | FansCount = 3000,
237 |
238 | CommentCount = 11,
239 | GiftCollectionCount = 5,
240 | GiftCount = 6,
241 | InteractionBegin = DateTime.Now.AddDays(-5),
242 | InteractionEnd = DateTime.Now,
243 | IsFansTeam = true,
244 | IsGiftCollection = true,
245 | Last7DaysComments = 4,
246 | Last7DaysGift = 1,
247 | Last7DaysView = 1,
248 | ViewDay = 3,
249 | ViewTime = 25
250 | });
251 |
252 | audienceModelList.Add(new AudienceModel()
253 | {
254 | Number = 4,
255 | Contribution = 10,
256 | Degree = 10,
257 | ImgLink = "Assets/Galgg.jpg",
258 | NickName = "Galgg",
259 | RelationShip = RelationShip.Friend,
260 | Location = "广州",
261 | InterestCount = 250,
262 | FansCount = 2000,
263 |
264 |
265 | CommentCount = 20,
266 | GiftCollectionCount = 3,
267 | GiftCount = 3,
268 | InteractionBegin = DateTime.Now.AddDays(-2),
269 | InteractionEnd = DateTime.Now,
270 | IsFansTeam = false,
271 | IsGiftCollection = true,
272 | Last7DaysComments = 7,
273 | Last7DaysGift = 24,
274 | Last7DaysView = 2,
275 | ViewDay = 4,
276 | ViewTime = 30
277 | });
278 |
279 | audienceModelList.Add(new AudienceModel()
280 | {
281 | Number = 5,
282 | Contribution = 10,
283 | Degree = 11,
284 | ImgLink = "Assets/lynnf.jpg",
285 | NickName = "Lynn*F",
286 | RelationShip = RelationShip.Friend,
287 | Location = "江苏",
288 | InterestCount = 350,
289 | FansCount = 2500,
290 |
291 |
292 | CommentCount = 2,
293 | GiftCollectionCount = 2,
294 | GiftCount = 9,
295 | InteractionBegin = DateTime.Now.AddDays(-4),
296 | InteractionEnd = DateTime.Now,
297 | IsFansTeam = false,
298 | IsGiftCollection = true,
299 | Last7DaysComments = 9,
300 | Last7DaysGift = 7,
301 | Last7DaysView = 6,
302 | ViewDay = 7,
303 | ViewTime = 18
304 | });
305 |
306 | audienceModelList.Add(new AudienceModel()
307 | {
308 | Number = 6,
309 | Contribution = 1,
310 | Degree = 3,
311 | ImgLink = "Assets/xiaoxianyu.jpg",
312 | NickName = "小咸鱼",
313 | RelationShip = RelationShip.Fans,
314 | Location = "浙江",
315 | InterestCount = 450,
316 | FansCount = 3500,
317 |
318 | CommentCount = 32,
319 | GiftCollectionCount = 1,
320 | GiftCount = 2,
321 | InteractionBegin = DateTime.Now.AddDays(-6),
322 | InteractionEnd = DateTime.Now,
323 | IsFansTeam = false,
324 | IsGiftCollection = true,
325 | Last7DaysComments = 7,
326 | Last7DaysGift = 3,
327 | Last7DaysView = 4,
328 | ViewDay = 6,
329 | ViewTime = 30
330 | });
331 |
332 | audienceModelList.Add(new AudienceModel()
333 | {
334 | Number = 7,
335 | Contribution = 0,
336 | Degree = 2,
337 | ImgLink = "Assets/xiaoxianyu.jpg",
338 | NickName = "路飞雪大马扁子~退钱",
339 | RelationShip = RelationShip.Fans,
340 | Location = "上海",
341 | InterestCount = 550,
342 | FansCount = 5500,
343 |
344 |
345 | CommentCount = 19,
346 | GiftCollectionCount = 0,
347 | GiftCount = 12,
348 | InteractionBegin = DateTime.Now.AddDays(-1),
349 | InteractionEnd = DateTime.Now,
350 | IsFansTeam = false,
351 | IsGiftCollection = true,
352 | Last7DaysComments = 7,
353 | Last7DaysGift = 3,
354 | Last7DaysView = 7,
355 | ViewDay = 5,
356 | ViewTime = 35
357 | });
358 | }
359 | return audienceModelList;
360 | }
361 | set
362 | {
363 | audienceModelList = value;
364 | this.OnPropertyChanged();
365 | }
366 | }
367 |
368 |
369 |
370 | private ObservableCollection msgModelPageList;
371 | ///
372 | /// 消息列表
373 | ///
374 | public ObservableCollection MsgModelPageList
375 | {
376 | get
377 | {
378 | if (msgModelPageList == null)
379 | {
380 | msgModelPageList = new ObservableCollection();
381 |
382 | msgModelPageList.Add(new MsgModel()
383 | {
384 | Id = Guid.NewGuid().ToString(),
385 | Degree = 10,
386 | MsgInfo = "高手高手高高手,求带",
387 | NickName = "慧眼早教",
388 | MsgType = MsgType.NormalMsg
389 | });
390 |
391 | msgModelPageList.Add(new MsgModel()
392 | {
393 | Id = Guid.NewGuid().ToString(),
394 | Degree = 10,
395 | MsgInfo = "你有一个margin 5,是不是这个",
396 | NickName = "阿胜",
397 | MsgType = MsgType.NormalMsg
398 | });
399 |
400 | msgModelPageList.Add(new MsgModel()
401 | {
402 | Id = Guid.NewGuid().ToString(),
403 | Degree = 10,
404 | MsgInfo = "是Guid类型的",
405 | NickName = "你好小峰峰",
406 | MsgType = MsgType.NormalMsg
407 | });
408 |
409 | msgModelPageList.Add(new MsgModel()
410 | {
411 | Id = Guid.NewGuid().ToString(),
412 | Degree = 26,
413 | MsgInfo = null,
414 | NickName = "Wang",
415 | IsFansTeam = false,
416 | MsgType = MsgType.Greeting
417 | });
418 |
419 | msgModelPageList.Add(new MsgModel()
420 | {
421 | Id = Guid.NewGuid().ToString(),
422 | Degree = 26,
423 | MsgInfo = null,
424 | NickName = "Wang",
425 | MsgType = MsgType.Interest
426 | });
427 |
428 | msgModelPageList.Add(new MsgModel()
429 | {
430 | Id = Guid.NewGuid().ToString(),
431 | Degree = 30,
432 | MsgInfo = null,
433 | NickName = "幸运王子",
434 | MsgType = MsgType.Greeting,
435 | IsFansTeam = false
436 | });
437 |
438 | msgModelPageList.Add(new MsgModel()
439 | {
440 | Id = Guid.NewGuid().ToString(),
441 | Degree = 30,
442 | MsgInfo = null,
443 | NickName = "璞",
444 | MsgType = MsgType.Greeting,
445 | IsFansTeam = true
446 | });
447 | }
448 | return msgModelPageList;
449 | }
450 | set
451 | {
452 | msgModelPageList = value;
453 | this.OnPropertyChanged();
454 | }
455 | }
456 |
457 |
458 | }
459 | }
460 |
--------------------------------------------------------------------------------
/RS.DouYinLearning/Models/AudienceModel.cs:
--------------------------------------------------------------------------------
1 | using RS.DouYinWidgets.Models;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Linq;
5 | using System.Text;
6 | using System.Threading.Tasks;
7 | using System.Xml.Linq;
8 |
9 | namespace RS.DouYinLearning.Models
10 | {
11 | public class AudienceModel: UserModel
12 | {
13 | private int number;
14 |
15 | ///
16 | /// 观众序号
17 | ///
18 |
19 | public int Number
20 | {
21 | get { return number; }
22 | set
23 | {
24 | number = value;
25 | this.OnPropertyChanged();
26 | }
27 | }
28 |
29 |
30 | private int contribution;
31 |
32 | ///
33 | /// 贡献度
34 | ///
35 |
36 | public int Contribution
37 | {
38 | get { return contribution; }
39 | set
40 | {
41 | contribution = value;
42 | this.OnPropertyChanged();
43 | }
44 | }
45 |
46 |
47 |
48 |
49 | private RelationShip relationShip;
50 |
51 | ///
52 | /// 关系
53 | ///
54 |
55 | public RelationShip RelationShip
56 | {
57 | get { return relationShip; }
58 | set
59 | {
60 | relationShip = value;
61 | this.OnPropertyChanged();
62 | }
63 | }
64 |
65 |
66 |
67 | private string imgLink;
68 |
69 | ///
70 | /// 头像地址
71 | ///
72 |
73 | public string ImgLink
74 | {
75 | get { return imgLink; }
76 | set
77 | {
78 | imgLink = value;
79 | this.OnPropertyChanged();
80 | }
81 | }
82 |
83 |
84 | private string location;
85 |
86 | ///
87 | /// 地址
88 | ///
89 |
90 | public string Location
91 | {
92 | get { return location; }
93 | set
94 | {
95 | location = value;
96 | this.OnPropertyChanged();
97 | }
98 | }
99 |
100 |
101 | private int interestCount;
102 |
103 | ///
104 | /// 关注数量
105 | ///
106 |
107 | public int InterestCount
108 | {
109 | get { return interestCount; }
110 | set
111 | {
112 | interestCount = value;
113 | this.OnPropertyChanged();
114 | }
115 | }
116 |
117 |
118 | private int fansCount;
119 |
120 | ///
121 | /// 粉丝数量
122 | ///
123 | public int FansCount
124 | {
125 | get { return fansCount; }
126 | set
127 | {
128 | fansCount = value;
129 | this.OnPropertyChanged();
130 | }
131 | }
132 |
133 |
134 | private long viewTime;
135 |
136 | ///
137 | /// 观看时长
138 | ///
139 | public long ViewTime
140 | {
141 | get { return viewTime; }
142 | set
143 | {
144 | viewTime = value;
145 | this.OnPropertyChanged();
146 | }
147 | }
148 |
149 |
150 | private long viewDay;
151 |
152 | ///
153 | /// 过去7天观看天数
154 | ///
155 | public long ViewDay
156 | {
157 | get { return viewDay; }
158 | set
159 | {
160 | viewDay = value;
161 | this.OnPropertyChanged();
162 | }
163 | }
164 |
165 | private int giftCount;
166 |
167 | ///
168 | /// 过去7天礼物数量
169 | ///
170 | public int GiftCount
171 | {
172 | get { return giftCount; }
173 | set
174 | {
175 | giftCount = value;
176 | this.OnPropertyChanged();
177 | }
178 | }
179 |
180 |
181 | private int commentCount;
182 |
183 | ///
184 | /// 过去7天评论数量
185 | ///
186 | public int CommentCount
187 | {
188 | get { return commentCount; }
189 | set
190 | {
191 | commentCount = value;
192 | this.OnPropertyChanged();
193 | }
194 | }
195 |
196 |
197 |
198 |
199 |
200 |
201 | private bool isGiftCollection;
202 |
203 | ///
204 | /// 是否有礼物图鉴
205 | ///
206 | public bool IsGiftCollection
207 | {
208 | get { return isGiftCollection; }
209 | set
210 | {
211 | isGiftCollection = value;
212 | this.OnPropertyChanged();
213 | }
214 | }
215 |
216 | private int giftCollectionCount;
217 |
218 | ///
219 | /// 礼物图鉴个数
220 | ///
221 | public int GiftCollectionCount
222 | {
223 | get { return giftCollectionCount; }
224 | set
225 | {
226 | giftCollectionCount = value;
227 | this.OnPropertyChanged();
228 | }
229 | }
230 |
231 |
232 | private DateTime interactionBegin;
233 |
234 | ///
235 | /// 互动开始时间
236 | ///
237 | public DateTime InteractionBegin
238 | {
239 | get { return interactionBegin; }
240 | set
241 | {
242 | interactionBegin = value;
243 | this.OnPropertyChanged();
244 | }
245 | }
246 |
247 |
248 | private DateTime interactionEnd;
249 |
250 | ///
251 | /// 互动开始时间结束
252 | ///
253 | public DateTime InteractionEnd
254 | {
255 | get { return interactionEnd; }
256 | set
257 | {
258 | interactionEnd = value;
259 | this.OnPropertyChanged();
260 | }
261 | }
262 |
263 |
264 | private int last7DaysView;
265 |
266 | ///
267 | /// 过去7天观看直播
268 | ///
269 | public int Last7DaysView
270 | {
271 | get { return last7DaysView; }
272 | set
273 | {
274 | last7DaysView = value;
275 | this.OnPropertyChanged();
276 | }
277 | }
278 |
279 |
280 | private int last7DaysGift;
281 |
282 | ///
283 | /// 过去7天观看直播
284 | ///
285 | public int Last7DaysGift
286 | {
287 | get { return last7DaysGift; }
288 | set
289 | {
290 | last7DaysGift = value;
291 | this.OnPropertyChanged();
292 | }
293 | }
294 |
295 |
296 | private int last7DaysComments;
297 |
298 | ///
299 | /// 过去7天观看直播
300 | ///
301 | public int Last7DaysComments
302 | {
303 | get { return last7DaysComments; }
304 | set
305 | {
306 | last7DaysComments = value;
307 | this.OnPropertyChanged();
308 | }
309 | }
310 |
311 | }
312 | }
313 |
--------------------------------------------------------------------------------
/RS.DouYinLearning/Models/MsgModel.cs:
--------------------------------------------------------------------------------
1 | using RS.DouYinWidgets.Models;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Linq;
5 | using System.Text;
6 | using System.Threading.Tasks;
7 |
8 | namespace RS.DouYinLearning.Models
9 | {
10 | public class MsgModel : UserModel
11 | {
12 | private string msgInfo;
13 |
14 | ///
15 | /// 消息
16 | ///
17 |
18 | public string MsgInfo
19 | {
20 | get { return msgInfo; }
21 | set
22 | {
23 | msgInfo = value;
24 | this.OnPropertyChanged();
25 | }
26 | }
27 |
28 |
29 | private MsgType msgType;
30 | ///
31 | /// 消息类型
32 | ///
33 |
34 | public MsgType MsgType
35 | {
36 | get { return msgType; }
37 | set
38 | {
39 | msgType = value;
40 | this.OnPropertyChanged();
41 | }
42 | }
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/RS.DouYinLearning/Models/MsgType.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace RS.DouYinLearning.Models
8 | {
9 | public enum MsgType
10 | {
11 | ///
12 | /// 这是普通消息
13 | ///
14 | NormalMsg,
15 |
16 | ///
17 | /// 这是欢迎高等级用户的消息
18 | ///
19 | Greeting,
20 |
21 | ///
22 | /// 这是用户点关注的消息
23 | ///
24 | Interest,
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/RS.DouYinLearning/Models/RelationShip.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace RS.DouYinLearning.Models
8 | {
9 | public enum RelationShip
10 | {
11 | ///
12 | /// 陌生人
13 | ///
14 | Stranger,
15 | ///
16 | /// 粉丝
17 | ///
18 | Fans,
19 | ///
20 | /// 朋友
21 | ///
22 | Friend
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/RS.DouYinLearning/Models/UserModel.cs:
--------------------------------------------------------------------------------
1 | using RS.DouYinWidgets.Models;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Linq;
5 | using System.Text;
6 | using System.Threading.Tasks;
7 |
8 | namespace RS.DouYinLearning.Models
9 | {
10 | public class UserModel : NotifyBase
11 | {
12 | ///
13 | /// 用户唯一标识
14 | ///
15 | public string Id { get; set; }
16 |
17 | private string nickName;
18 |
19 | ///
20 | /// 观众昵称
21 | ///
22 |
23 | public string NickName
24 | {
25 | get { return nickName; }
26 | set
27 | {
28 | nickName = value;
29 | this.OnPropertyChanged();
30 | }
31 | }
32 |
33 | private int degree;
34 |
35 | ///
36 | /// 抖音等级
37 | ///
38 |
39 | public int Degree
40 | {
41 | get { return degree; }
42 | set
43 | {
44 | degree = value;
45 | this.OnPropertyChanged();
46 | }
47 | }
48 |
49 |
50 | private bool isFansTeam;
51 |
52 | ///
53 | /// 是否加入粉丝团
54 | ///
55 | public bool IsFansTeam
56 | {
57 | get { return isFansTeam; }
58 | set
59 | {
60 | isFansTeam = value;
61 | this.OnPropertyChanged();
62 | }
63 | }
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/RS.DouYinLearning/RS - Backup.DouYinLearning.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | WinExe
5 | net8.0-windows
6 | enable
7 | enable
8 | true
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 | Always
39 |
40 |
41 |
42 |
43 |
--------------------------------------------------------------------------------
/RS.DouYinLearning/RS.DouYinLearning.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | WinExe
5 | net8.0-windows
6 | enable
7 | enable
8 | true
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 | Always
47 |
48 |
49 |
50 |
51 |
--------------------------------------------------------------------------------
/RS.DouYinUsercontrol/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Windows;
2 | using System.Windows.Markup;
3 |
4 | [assembly: ThemeInfo(ResourceDictionaryLocation.None, ResourceDictionaryLocation.SourceAssembly )]
5 | [assembly: XmlnsPrefix("https://streamingtool.douyin.com/wpf/learning/2024", "rs")]
6 | [assembly: XmlnsDefinition("https://streamingtool.douyin.com/wpf/learning/2024", "RS.DouYinUsercontrol")]
7 |
--------------------------------------------------------------------------------
/RS.DouYinUsercontrol/RS.DouYinUsercontrol.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net8.0-windows
5 | enable
6 | true
7 | enable
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/RS.DouYinUsercontrol/WinMonitorBtn.xaml:
--------------------------------------------------------------------------------
1 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
185 |
186 |
187 |
--------------------------------------------------------------------------------
/RS.DouYinUsercontrol/WinMonitorBtn.xaml.cs:
--------------------------------------------------------------------------------
1 | using RS.DouYinWidgets.Events;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Linq;
5 | using System.Text;
6 | using System.Threading.Tasks;
7 | using System.Windows;
8 | using System.Windows.Controls;
9 | using System.Windows.Data;
10 | using System.Windows.Documents;
11 | using System.Windows.Input;
12 | using System.Windows.Media;
13 | using System.Windows.Media.Imaging;
14 | using System.Windows.Navigation;
15 | using System.Windows.Shapes;
16 |
17 | namespace RS.DouYinUsercontrol
18 | {
19 | ///
20 | /// WinMonitorBtn.xaml 的交互逻辑
21 | ///
22 | public partial class WinMonitorBtn : RadioButton, IDrag
23 | {
24 | public WinMonitorBtn()
25 | {
26 | InitializeComponent();
27 | }
28 |
29 | ///
30 | /// 这就是路由事件
31 | ///
32 | public static readonly RoutedEvent LockMaterialsClickEvent = EventManager.RegisterRoutedEvent(
33 | "LockMaterialsClick", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(WinMonitorBtn));
34 |
35 | public event RoutedEventHandler LockMaterialsClick
36 | {
37 | add { AddHandler(LockMaterialsClickEvent, value); }
38 | remove { RemoveHandler(LockMaterialsClickEvent, value); }
39 | }
40 |
41 | ///
42 | /// 这个是普通事件 这种事件它不会触发什么冒泡或者隧道之类
43 | ///
44 | public event Action OnEyeShowHideClick;
45 |
46 |
47 | private void PART_CkEyeShowHide_Click(object sender, RoutedEventArgs e)
48 | {
49 | var checkBox = sender as CheckBox;
50 | OnEyeShowHideClick?.Invoke(this, checkBox.IsChecked == true);
51 | }
52 |
53 | private void PART_CkLockUnLock_Click(object sender, RoutedEventArgs e)
54 | {
55 | var checkBox = sender as CheckBox;
56 | // 触发自定义的路由事件
57 | RoutedEventArgs args = new RoutedEventArgs(LockMaterialsClickEvent, checkBox.IsChecked == true);
58 | RaiseEvent(args);
59 | }
60 |
61 | private void BtnPositionReset_Click(object sender, RoutedEventArgs e)
62 | {
63 |
64 | }
65 |
66 | private void BtnReName_Click(object sender, RoutedEventArgs e)
67 | {
68 |
69 | }
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/RS.DouYinWidgets/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Windows;
2 | using System.Windows.Markup;
3 |
4 | [assembly: ThemeInfo(ResourceDictionaryLocation.None, ResourceDictionaryLocation.SourceAssembly)]
5 | [assembly: XmlnsPrefix("https://streamingtool.douyin.com/wpf/learning/2024", "rs")]
6 | [assembly: XmlnsDefinition("https://streamingtool.douyin.com/wpf/learning/2024", "RS.DouYinWidgets")]
7 | [assembly: XmlnsDefinition("https://streamingtool.douyin.com/wpf/learning/2024", "RS.DouYinWidgets.Controls")]
--------------------------------------------------------------------------------
/RS.DouYinWidgets/Controls/ControlsCommand.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Security.Permissions;
5 | using System.Security;
6 | using System.Text;
7 | using System.Threading.Tasks;
8 | using System.Windows.Input;
9 | using System.Windows.Interop;
10 | using System.Windows;
11 | using RS.DouYinWidgets.Events;
12 | using System.Windows.Controls;
13 |
14 | namespace RS.DouYinWidgets.Controls
15 | {
16 | public static class ControlsCommand
17 | {
18 |
19 | public static RoutedCommand CleanTextCommand { get; private set; }
20 |
21 | static ControlsCommand()
22 | {
23 | CleanTextCommand = new RoutedCommand("CleanText", typeof(ControlsCommand));
24 | }
25 |
26 | public static void CleanText(object source)
27 | {
28 | if (source is TextBox textBox)
29 | {
30 | textBox.Text = string.Empty;
31 | }
32 | }
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/RS.DouYinWidgets/Controls/ControlsHelper.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using System.Windows;
7 | using System.Windows.Media;
8 |
9 | namespace RS.DouYinWidgets.Controls
10 | {
11 | public static class ControlsHelper
12 | {
13 |
14 | ///
15 | /// 这是自定义Pata 路径
16 | ///
17 | public static readonly DependencyProperty IconDataProperty =
18 | DependencyProperty.RegisterAttached(
19 | "IconData",
20 | typeof(Geometry),
21 | typeof(ControlsHelper),
22 | new PropertyMetadata(null));
23 |
24 | public static Geometry GetIconData(DependencyObject obj)
25 | {
26 | return (Geometry)obj.GetValue(IconDataProperty);
27 | }
28 |
29 | public static void SetIconData(DependencyObject obj, Geometry value)
30 | {
31 | obj.SetValue(IconDataProperty, value);
32 | }
33 |
34 |
35 | ///
36 | /// 这是Icon宽度
37 | ///
38 |
39 | public static readonly DependencyProperty IconWidthProperty =
40 | DependencyProperty.RegisterAttached(
41 | "IconWidth",
42 | typeof(double),
43 | typeof(ControlsHelper),
44 | new PropertyMetadata(15D));
45 |
46 | public static double GetIconWidth(DependencyObject obj)
47 | {
48 | return (double)obj.GetValue(IconWidthProperty);
49 | }
50 |
51 | public static void SetIconWidth(DependencyObject obj, double value)
52 | {
53 | obj.SetValue(IconWidthProperty, value);
54 | }
55 |
56 |
57 | ///
58 | /// 这是Icon高度
59 | ///
60 | public static readonly DependencyProperty IconHeightProperty =
61 | DependencyProperty.RegisterAttached(
62 | "IconHeight",
63 | typeof(double),
64 | typeof(ControlsHelper),
65 | new PropertyMetadata(15D));
66 |
67 | public static double GetIconHeight(DependencyObject obj)
68 | {
69 | return (double)obj.GetValue(IconHeightProperty);
70 | }
71 |
72 | public static void SetIconHeight(DependencyObject obj, double value)
73 | {
74 | obj.SetValue(IconHeightProperty, value);
75 | }
76 |
77 |
78 |
79 | ///
80 | /// 设置空间圆角
81 | ///
82 | public static readonly DependencyProperty CornerRadiusProperty =
83 | DependencyProperty.RegisterAttached(
84 | "CornerRadius",
85 | typeof(CornerRadius),
86 | typeof(ControlsHelper),
87 | new PropertyMetadata(default));
88 |
89 | public static CornerRadius GetCornerRadius(DependencyObject obj)
90 | {
91 | return (CornerRadius)obj.GetValue(CornerRadiusProperty);
92 | }
93 |
94 | public static void SetCornerRadius(DependencyObject obj, CornerRadius value)
95 | {
96 | obj.SetValue(CornerRadiusProperty, value);
97 | }
98 |
99 |
100 |
101 |
102 | }
103 | }
104 |
--------------------------------------------------------------------------------
/RS.DouYinWidgets/Controls/DragAdorner.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Reflection;
5 | using System.Text;
6 | using System.Threading.Tasks;
7 | using System.Windows;
8 | using System.Windows.Controls;
9 | using System.Windows.Controls.Primitives;
10 | using System.Windows.Documents;
11 | using System.Windows.Input;
12 | using System.Windows.Media;
13 | using System.Windows.Media.Animation;
14 | using System.Windows.Media.Imaging;
15 | using System.Windows.Shapes;
16 |
17 | namespace RS.DouYinWidgets.Controls
18 | {
19 | public class DragAdorner : Adorner
20 | {
21 | private readonly Rectangle _child;
22 | private double _leftOffset;
23 | private double _topOffset;
24 | // Be sure to call the base class constructor.
25 | public DragAdorner(UIElement adornedElement)
26 | : base(adornedElement)
27 | {
28 | var brush = new VisualBrush(adornedElement);
29 | _child = new Rectangle
30 | {
31 | Width = adornedElement.RenderSize.Width,
32 | Height = adornedElement.RenderSize.Height
33 | };
34 | _child.Fill = brush;
35 | }
36 |
37 | protected override int VisualChildrenCount => 1;
38 |
39 | public double LeftOffset
40 | {
41 | get { return _leftOffset; }
42 | set
43 | {
44 | _leftOffset = value;
45 | UpdatePosition();
46 | }
47 | }
48 |
49 | public double TopOffset
50 | {
51 | get { return _topOffset; }
52 | set
53 | {
54 | _topOffset = value;
55 | UpdatePosition();
56 | }
57 | }
58 |
59 | // A common way to implement an adorner's rendering behavior is to override the OnRender
60 | // method, which is called by the layout subsystem as part of a rendering pass.
61 | protected override void OnRender(DrawingContext drawingContext)
62 | {
63 | // Get a rectangle that represents the desired size of the rendered element
64 | // after the rendering pass. This will be used to draw at the corners of the
65 | // adorned element.
66 | var adornedElementRect = new Rect(AdornedElement.DesiredSize);
67 |
68 | // Some arbitrary drawing implements.
69 | var renderBrush = new SolidColorBrush(Colors.Green) { Opacity = 0.2 };
70 | var renderPen = new Pen(new SolidColorBrush(Colors.Navy), 1.5);
71 | const double renderRadius = 5.0;
72 |
73 | // Just draw a circle at each corner.
74 | drawingContext.DrawRectangle(renderBrush, renderPen, adornedElementRect);
75 | drawingContext.DrawEllipse(renderBrush, renderPen, adornedElementRect.TopLeft, renderRadius, renderRadius);
76 | drawingContext.DrawEllipse(renderBrush, renderPen, adornedElementRect.TopRight, renderRadius, renderRadius);
77 | drawingContext.DrawEllipse(renderBrush, renderPen, adornedElementRect.BottomLeft, renderRadius, renderRadius);
78 | drawingContext.DrawEllipse(renderBrush, renderPen, adornedElementRect.BottomRight, renderRadius,
79 | renderRadius);
80 | }
81 |
82 | protected override Size MeasureOverride(Size constraint)
83 | {
84 | _child.Measure(constraint);
85 | return _child.DesiredSize;
86 | }
87 |
88 | protected override Size ArrangeOverride(Size finalSize)
89 | {
90 | _child.Arrange(new Rect(finalSize));
91 | return finalSize;
92 | }
93 |
94 | protected override Visual GetVisualChild(int index) => _child;
95 |
96 | private void UpdatePosition()
97 | {
98 | var adornerLayer = Parent as AdornerLayer;
99 | adornerLayer?.Update(AdornedElement);
100 | }
101 |
102 | public override GeneralTransform GetDesiredTransform(GeneralTransform transform)
103 | {
104 | var result = new GeneralTransformGroup();
105 | result.Children.Add(base.GetDesiredTransform(transform));
106 | result.Children.Add(new TranslateTransform(_leftOffset, _topOffset));
107 | return result;
108 | }
109 | }
110 | }
111 |
112 |
--------------------------------------------------------------------------------
/RS.DouYinWidgets/Controls/RSDouYinWindow.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using System.Windows;
7 | using System.Windows.Controls;
8 | using System.Windows.Input;
9 |
10 | namespace RS.DouYinWidgets.Controls
11 | {
12 | public class RSDouYinWindow : Window
13 | {
14 | static RSDouYinWindow()
15 | {
16 | DefaultStyleKeyProperty.OverrideMetadata(typeof(RSDouYinWindow), new FrameworkPropertyMetadata(typeof(RSDouYinWindow)));
17 | }
18 |
19 | public RSDouYinWindow()
20 | {
21 | this.CommandBindings.Add(new CommandBinding(SystemCommands.CloseWindowCommand, CloseWindow));
22 | this.CommandBindings.Add(new CommandBinding(SystemCommands.MaximizeWindowCommand, MaximizeWindow, CanResizeWindow));
23 | this.CommandBindings.Add(new CommandBinding(SystemCommands.MinimizeWindowCommand, MinimizeWindow, CanMinimizeWindow));
24 | this.CommandBindings.Add(new CommandBinding(SystemCommands.RestoreWindowCommand, RestoreWindow, CanResizeWindow));
25 | this.CommandBindings.Add(new CommandBinding(SystemCommands.ShowSystemMenuCommand, ShowSystemMenu));
26 |
27 | // 添加命令绑定
28 | this.CommandBindings.Add(new CommandBinding(ControlsCommand.CleanTextCommand, CleanTextText));
29 | }
30 |
31 | private void CleanTextText(object sender, ExecutedRoutedEventArgs e)
32 | {
33 | ControlsCommand.CleanText(e.Source);
34 | }
35 |
36 | private void ShowSystemMenu(object sender, ExecutedRoutedEventArgs e)
37 | {
38 | var element = e.OriginalSource as FrameworkElement;
39 | if (element == null)
40 | {
41 | return;
42 | }
43 | var point = WindowState.Maximized == this.WindowState ? new Point(0, element.ActualHeight) : new Point(Left + BorderThickness.Left, element.ActualHeight + Top + BorderThickness.Top);
44 | point = element.TransformToAncestor(this).Transform(point);
45 | SystemCommands.ShowSystemMenu(this, point);
46 | }
47 |
48 | private void CanMinimizeWindow(object sender, CanExecuteRoutedEventArgs e)
49 | {
50 | e.CanExecute = this.ResizeMode != ResizeMode.NoResize;
51 | }
52 |
53 | private void RestoreWindow(object sender, ExecutedRoutedEventArgs e)
54 | {
55 | SystemCommands.RestoreWindow(this);
56 | }
57 |
58 | private void MinimizeWindow(object sender, ExecutedRoutedEventArgs e)
59 | {
60 | SystemCommands.MinimizeWindow(this);
61 | }
62 |
63 | private void CanResizeWindow(object sender, CanExecuteRoutedEventArgs e)
64 | {
65 | e.CanExecute = this.ResizeMode == ResizeMode.CanResize || ResizeMode == ResizeMode.CanResizeWithGrip;
66 | }
67 |
68 |
69 | private void MaximizeWindow(object sender, ExecutedRoutedEventArgs e)
70 | {
71 | SystemCommands.MaximizeWindow(this);
72 | }
73 |
74 | private void CloseWindow(object sender, ExecutedRoutedEventArgs e)
75 | {
76 | SystemCommands.CloseWindow(this);
77 | }
78 |
79 |
80 | ///
81 | /// 窗体顶部自定义内容
82 | ///
83 | public object WinCommandContent
84 | {
85 | get { return (object)GetValue(WinCommandContentProperty); }
86 | set { SetValue(WinCommandContentProperty, value); }
87 | }
88 |
89 | public static readonly DependencyProperty WinCommandContentProperty =
90 | DependencyProperty.Register("WinCommandContent", typeof(object), typeof(RSDouYinWindow), new PropertyMetadata(null));
91 |
92 |
93 |
94 | }
95 | }
96 |
--------------------------------------------------------------------------------
/RS.DouYinWidgets/Controls/RSDropDownBtn.cs:
--------------------------------------------------------------------------------
1 | using RS.DouYinWidgets.Events;
2 | using RS.DouYinWidgets.Models;
3 | using System;
4 | using System.Collections.Generic;
5 | using System.Collections.ObjectModel;
6 | using System.Linq;
7 | using System.Net.Http.Headers;
8 | using System.Text;
9 | using System.Threading.Tasks;
10 | using System.Windows;
11 | using System.Windows.Controls.Primitives;
12 |
13 | namespace RS.DouYinWidgets.Controls
14 | {
15 | public class RSDropDownBtn : ToggleButton, IDrag
16 | {
17 | static RSDropDownBtn()
18 | {
19 | DefaultStyleKeyProperty.OverrideMetadata(typeof(RSDropDownBtn), new FrameworkPropertyMetadata(typeof(RSDropDownBtn)));
20 | }
21 |
22 |
23 |
24 |
25 | public ObservableCollection ButtonModelList
26 | {
27 | get { return (ObservableCollection)GetValue(ButtonModelListProperty); }
28 | set { SetValue(ButtonModelListProperty, value); }
29 | }
30 |
31 | public static readonly DependencyProperty ButtonModelListProperty =
32 | DependencyProperty.Register("ButtonModelList", typeof(ObservableCollection), typeof(RSDropDownBtn), new PropertyMetadata(null, ButtonModelListPropertyChanged));
33 |
34 | private static void ButtonModelListPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
35 | {
36 | var rsDropDownBtn = d as RSDropDownBtn;
37 | rsDropDownBtn.InitDefaultConfig();
38 | }
39 |
40 |
41 | private void InitDefaultConfig()
42 | {
43 | if (this.PopRows == 0)
44 | {
45 | var rows = ButtonModelList.Count;
46 | if (this.PopCols > 0)
47 | {
48 | rows = (int)Math.Ceiling((double)rows / this.PopCols);
49 | }
50 | this.PopRows = rows;
51 | }
52 | }
53 |
54 |
55 | public int PopCols
56 | {
57 | get { return (int)GetValue(PopColsProperty); }
58 | set { SetValue(PopColsProperty, value); }
59 | }
60 |
61 | public static readonly DependencyProperty PopColsProperty =
62 | DependencyProperty.Register("PopCols", typeof(int), typeof(RSDropDownBtn), new PropertyMetadata(1));
63 |
64 |
65 | public int PopRows
66 | {
67 | get { return (int)GetValue(PopRowsProperty); }
68 | set { SetValue(PopRowsProperty, value); }
69 | }
70 | public static readonly DependencyProperty PopRowsProperty =
71 | DependencyProperty.Register("PopRows", typeof(int), typeof(RSDropDownBtn), new PropertyMetadata(0));
72 |
73 |
74 |
75 |
76 | public double PopWidth
77 | {
78 | get { return (double)GetValue(PopWidthProperty); }
79 | set { SetValue(PopWidthProperty, value); }
80 | }
81 |
82 | public static readonly DependencyProperty PopWidthProperty =
83 | DependencyProperty.Register("PopWidth", typeof(double), typeof(RSDropDownBtn), new PropertyMetadata(200D));
84 |
85 |
86 |
87 |
88 |
89 | public double PopHeight
90 | {
91 | get { return (double)GetValue(PopHeightProperty); }
92 | set { SetValue(PopHeightProperty, value); }
93 | }
94 |
95 | public static readonly DependencyProperty PopHeightProperty =
96 | DependencyProperty.Register("PopHeight", typeof(double), typeof(RSDropDownBtn), new PropertyMetadata(200D));
97 |
98 |
99 |
100 |
101 |
102 | public int BtnGroupIndex
103 | {
104 | get { return (int)GetValue(BtnGroupIndexProperty); }
105 | set { SetValue(BtnGroupIndexProperty, value); }
106 | }
107 |
108 | public static readonly DependencyProperty BtnGroupIndexProperty =
109 | DependencyProperty.Register("BtnGroupIndex", typeof(int), typeof(RSDropDownBtn), new PropertyMetadata(0));
110 |
111 |
112 |
113 | public override void OnApplyTemplate()
114 | {
115 | base.OnApplyTemplate();
116 | }
117 | }
118 | }
119 |
--------------------------------------------------------------------------------
/RS.DouYinWidgets/Controls/RSPopBtn.cs:
--------------------------------------------------------------------------------
1 | using RS.DouYinWidgets.Events;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Linq;
5 | using System.Text;
6 | using System.Threading.Tasks;
7 | using System.Windows;
8 | using System.Windows.Controls;
9 | using System.Windows.Controls.Primitives;
10 |
11 | namespace RS.DouYinWidgets.Controls
12 | {
13 |
14 | [TemplatePart(Name = nameof(PART_Popup), Type = typeof(Popup))]
15 | [TemplatePart(Name = nameof(PART_PopBoder), Type = typeof(Border))]
16 | public class RSPopBtn : ToggleButton,IDrag
17 | {
18 | private Popup PART_Popup;
19 | private Border PART_PopBoder;
20 | static RSPopBtn()
21 | {
22 | DefaultStyleKeyProperty.OverrideMetadata(typeof(RSPopBtn), new FrameworkPropertyMetadata(typeof(RSPopBtn)));
23 | }
24 |
25 | public RSPopBtn()
26 | {
27 |
28 | }
29 |
30 |
31 | public ControlTemplate PopContentTemplate
32 | {
33 | get { return (ControlTemplate)GetValue(PopContentTemplateProperty); }
34 | set { SetValue(PopContentTemplateProperty, value); }
35 | }
36 |
37 | public static readonly DependencyProperty PopContentTemplateProperty =
38 | DependencyProperty.Register("PopContentTemplate", typeof(ControlTemplate), typeof(RSPopBtn), new PropertyMetadata(null));
39 |
40 |
41 |
42 | public override void OnApplyTemplate()
43 | {
44 | base.OnApplyTemplate();
45 | this.PART_Popup = (Popup)this.GetTemplateChild(nameof(this.PART_Popup));
46 | this.PART_PopBoder = (Border)this.GetTemplateChild(nameof(this.PART_PopBoder));
47 |
48 | //this.MouseEnter -= RSPopBtn_MouseEnter;
49 | //this.MouseEnter += RSPopBtn_MouseEnter;
50 |
51 | if (this.PART_Popup != null)
52 | {
53 | this.PART_Popup.Opened += PART_Popup_Opened;
54 | }
55 | }
56 |
57 |
58 | private void PART_Popup_Opened(object? sender, EventArgs e)
59 | {
60 | //var ellipsisBtnActualWidth = this.PART_EllipsisBtn.ActualWidth;
61 | //var popupActualWidth = ((Border)this.PART_Popup.Child).ActualWidth;
62 | //this.PART_Popup.HorizontalOffset = -popupActualWidth + ellipsisBtnActualWidth;
63 | //this.PART_Popup.VerticalOffset = 8;
64 | this.PART_Popup.VerticalOffset = this.Padding.Bottom + 2;
65 | }
66 |
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/RS.DouYinWidgets/Controls/RSSceneBtn.cs:
--------------------------------------------------------------------------------
1 | using RS.DouYinWidgets.Events;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Linq;
5 | using System.Text;
6 | using System.Threading.Tasks;
7 | using System.Windows;
8 | using System.Windows.Controls;
9 | using System.Windows.Controls.Primitives;
10 |
11 | namespace RS.DouYinWidgets.Controls
12 | {
13 |
14 | [TemplatePart(Name = nameof(PART_ContentHost), Type = typeof(Grid))]
15 | [TemplatePart(Name = nameof(PART_Border), Type = typeof(Border))]
16 |
17 | public class RSSceneBtn : RadioButton, IDrag
18 | {
19 | private Grid PART_ContentHost;
20 | private Border PART_Border;
21 | static RSSceneBtn()
22 | {
23 | DefaultStyleKeyProperty.OverrideMetadata(typeof(RSSceneBtn), new FrameworkPropertyMetadata(typeof(RSSceneBtn)));
24 | }
25 |
26 | public RSSceneBtn()
27 | {
28 |
29 | }
30 |
31 |
32 |
33 |
34 |
35 | public ControlTemplate PopContentTemplate
36 | {
37 | get { return (ControlTemplate)GetValue(PopContentTemplateProperty); }
38 | set { SetValue(PopContentTemplateProperty, value); }
39 | }
40 |
41 | public static readonly DependencyProperty PopContentTemplateProperty =
42 | DependencyProperty.Register("PopContentTemplate", typeof(ControlTemplate), typeof(RSSceneBtn), new PropertyMetadata(null));
43 |
44 |
45 | public override void OnApplyTemplate()
46 | {
47 | base.OnApplyTemplate();
48 | this.PART_ContentHost = (Grid)this.GetTemplateChild(nameof(this.PART_ContentHost));
49 | this.PART_Border = (Border)this.GetTemplateChild(nameof(this.PART_Border));
50 | }
51 |
52 |
53 |
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/RS.DouYinWidgets/Controls/TextBoxHelper.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using System.Windows;
7 | using System.Windows.Media;
8 |
9 | namespace RS.DouYinWidgets.Controls
10 | {
11 | public static class TextBoxHelper
12 | {
13 |
14 | ///
15 | /// 文本框输入水印
16 | ///
17 | public static readonly DependencyProperty WatermarkProperty =
18 | DependencyProperty.RegisterAttached("Watermark", typeof(string), typeof(TextBoxHelper), new PropertyMetadata("请输入内容..."));
19 |
20 | public static string GetWatermark(DependencyObject obj)
21 | {
22 | return (string)obj.GetValue(WatermarkProperty);
23 | }
24 |
25 | public static void SetWatermark(DependencyObject obj, string value)
26 | {
27 | obj.SetValue(WatermarkProperty, value);
28 | }
29 |
30 |
31 | ///
32 | /// 是否显示清除按钮
33 | ///
34 | public static readonly DependencyProperty IsShowClearBtnProperty =
35 | DependencyProperty.RegisterAttached("IsShowClearBtn", typeof(bool), typeof(TextBoxHelper), new PropertyMetadata(false));
36 |
37 | public static bool GetIsShowClearBtn(DependencyObject obj)
38 | {
39 | return (bool)obj.GetValue(IsShowClearBtnProperty);
40 | }
41 |
42 | public static void SetIsShowClearBtn(DependencyObject obj, bool value)
43 | {
44 | obj.SetValue(IsShowClearBtnProperty, value);
45 | }
46 | }
47 |
48 | }
49 |
--------------------------------------------------------------------------------
/RS.DouYinWidgets/Events/IDrag.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace RS.DouYinWidgets.Events
8 | {
9 | public interface IDrag
10 | {
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/RS.DouYinWidgets/Events/RelayCommand.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using System.Windows.Input;
7 |
8 | namespace RS.DouYinWidgets.Events
9 | {
10 | public class RelayCommand : ICommand
11 | {
12 | private readonly Action